plugins/core/metrics/bridge.go (174 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package metrics func newMeterOpts() *Opts { return &Opts{Labels: make(map[string]string)} } func (b *Opts) GetLabels() map[string]string { return b.Labels } type counterImpl struct { name string val float64 labels map[string]string getFunc func() float64 addFunc func(float64) } func newDefaultCounter(name string, opt ...Opt) *counterImpl { result := &counterImpl{name: name, val: 0} opts := newMeterOpts() for _, o := range opt { o(opts) } result.labels = opts.GetLabels() result.getFunc = func() float64 { return result.val } result.addFunc = func(f float64) { result.val += f } return result } func (c *counterImpl) Name() string { return c.name } func (c *counterImpl) Get() float64 { return c.getFunc() } func (c *counterImpl) Labels() map[string]string { return c.labels } func (c *counterImpl) Inc(val float64) { c.addFunc(val) } func (c *counterImpl) ChangeFunctions(add func(v float64), get func() float64) { c.addFunc = add c.getFunc = get } type gaugeImpl struct { name string labels map[string]string getter func() float64 } func newDefaultGauge(name string, getter func() float64, opt ...Opt) *gaugeImpl { result := &gaugeImpl{name: name, getter: getter} opts := newMeterOpts() for _, o := range opt { o(opts) } result.labels = opts.GetLabels() return result } func (g *gaugeImpl) Name() string { return g.name } func (g *gaugeImpl) Labels() map[string]string { return g.labels } func (g *gaugeImpl) Get() float64 { return g.getter() } func (g *gaugeImpl) Getter() func() float64 { return g.getter } type histogramImpl struct { name string labels map[string]string buckets []*histogramBucket observeFunc func(float64) observeWithCountFunc func(float64, int64) } type histogramBucket struct { bucket float64 val *int64 } func newDefaultHistogram(name string, minVal float64, steps []float64, opt ...Opt) *histogramImpl { result := &histogramImpl{name: name} opts := newMeterOpts() for _, o := range opt { o(opts) } result.labels = opts.GetLabels() result.initBuckets(minVal, steps) result.observeFunc = func(f float64) { b := result.findBucket(f) if b != nil { *b.val++ } } result.observeWithCountFunc = func(f float64, c int64) { b := result.findBucket(f) if b != nil { *b.val += c } } return result } func (h *histogramImpl) Observe(val float64) { h.observeFunc(val) } func (h *histogramImpl) ObserveWithCount(val float64, c int64) { h.observeWithCountFunc(val, c) } func (h *histogramImpl) findBucket(v float64) *histogramBucket { var low, high = 0, len(h.buckets) - 1 for low <= high { var mid = (low + high) / 2 if h.buckets[mid].bucket < v { low = mid + 1 } else if h.buckets[mid].bucket > v { high = mid - 1 } else { return h.buckets[mid] } } low-- if low < len(h.buckets) && low >= 0 { return h.buckets[low] } return nil } func (h *histogramImpl) initBuckets(minVal float64, steps []float64) { n := len(steps) for i := 1; i < n; i++ { key := steps[i] j := i - 1 if steps[j] == key { panic("duplicate steps found") } for j >= 0 && steps[j] > key { steps[j+1] = steps[j] j-- } steps[j+1] = key } if steps[0] != minVal { steps = append([]float64{minVal}, steps...) } buckets := make([]*histogramBucket, len(steps)) for i, step := range steps { buckets[i] = &histogramBucket{bucket: step, val: new(int64)} } h.buckets = buckets } func (h *histogramImpl) Name() string { return h.name } func (h *histogramImpl) Labels() map[string]string { return h.labels } func (h *histogramImpl) Buckets() []interface{} { result := make([]interface{}, len(h.buckets)) for i, b := range h.buckets { result[i] = b } return result } func (h *histogramImpl) ChangeFunctions(observe func(v float64), observeWithCount func(v float64, c int64)) { h.observeFunc = observe h.observeWithCountFunc = observeWithCount } func (h *histogramBucket) Bucket() float64 { return h.bucket } func (h *histogramBucket) Value() *int64 { return h.val }