Codebase list golang-github-go-kit-kit / 32d7a0b
Added Gauge.Add Daniel Middlecote authored 7 years ago Daniel Middlecote committed 7 years ago
15 changed file(s) with 134 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
11 package circonus
22
33 import (
4 "sync"
5
46 "github.com/circonus-labs/circonus-gometrics"
57
68 "github.com/go-kit/kit/metrics"
6264 type Gauge struct {
6365 name string
6466 m *circonusgometrics.CirconusMetrics
67 val float64
68 mtx sync.RWMutex
6569 }
6670
6771 // With implements Gauge, but is a no-op, because Circonus metrics have no
6973 func (g *Gauge) With(labelValues ...string) metrics.Gauge { return g }
7074
7175 // Set implements Gauge.
72 func (g *Gauge) Set(value float64) { g.m.SetGauge(g.name, value) }
76 func (g *Gauge) Set(value float64) {
77 g.mtx.Lock()
78 defer g.mtx.Unlock()
79 g.val = value
80 g.m.SetGauge(g.name, value)
81 }
82
83 // Add implements metrics.Gauge.
84 func (g *Gauge) Add(delta float64) {
85 g.mtx.Lock()
86 defer g.mtx.Unlock()
87 value := g.val + delta
88 g.val = value
89 g.m.SetGauge(g.name, value)
90 }
7391
7492 // Histogram is a Circonus implementation of a histogram metric.
7593 type Histogram struct {
2424 // Set implements Gauge.
2525 func (g gauge) Set(value float64) {}
2626
27 // Add implements metrics.Gauge.
28 func (g gauge) Add(delta float64) {}
29
2730 type histogram struct{}
2831
2932 // NewHistogram returns a new no-op histogram.
7171 return &Gauge{
7272 name: d.prefix + name,
7373 obs: d.gauges.Observe,
74 add: d.gauges.Add,
7475 }
7576 }
7677
243244 name string
244245 lvs lv.LabelValues
245246 obs observeFunc
247 add observeFunc
246248 }
247249
248250 // With implements metrics.Gauge.
251253 name: g.name,
252254 lvs: g.lvs.With(labelValues...),
253255 obs: g.obs,
256 add: g.add,
254257 }
255258 }
256259
257260 // Set implements metrics.Gauge.
258261 func (g *Gauge) Set(value float64) {
259262 g.obs(g.name, g.lvs, value)
263 }
264
265 // Add implements metrics.Gauge.
266 func (g *Gauge) Add(delta float64) {
267 g.add(g.name, g.lvs, delta)
260268 }
261269
262270 // Timing is a DogStatsD timing, or metrics.Histogram. Observations are
4949 // Set implements Gauge.
5050 func (g *Gauge) Set(value float64) { g.f.Set(value) }
5151
52 // Add implements metrics.Gauge.
53 func (g *Gauge) Add(delta float64) { g.f.Add(delta) }
54
5255 // Histogram implements the histogram metric with a combination of the generic
5356 // Histogram object and several expvar Floats, one for each of the 50th, 90th,
5457 // 95th, and 99th quantiles of observed values, with the quantile attached to
104104 atomic.StoreUint64(&g.bits, math.Float64bits(value))
105105 }
106106
107 // Add implements metrics.Gauge.
108 func (g *Gauge) Add(delta float64) {
109 for {
110 var (
111 old = atomic.LoadUint64(&g.bits)
112 newf = math.Float64frombits(old) + delta
113 new = math.Float64bits(newf)
114 )
115 if atomic.CompareAndSwapUint64(&g.bits, old, new) {
116 break
117 }
118 }
119 }
120
107121 // Value returns the current value of the gauge.
108122 func (g *Gauge) Value() float64 {
109123 return math.Float64frombits(atomic.LoadUint64(&g.bits))
181181 // Set implements gauge.
182182 func (g *Gauge) Set(value float64) { g.g.Set(value) }
183183
184 // Add implements metrics.Gauge.
185 func (g *Gauge) Add(delta float64) { g.g.Add(delta) }
186
184187 // Histogram is a Graphite histogram metric. Observations are bucketed into
185188 // per-quantile gauges.
186189 type Histogram struct {
4343 gauge.With("error", "true").Set(1)
4444 gauge.With("error", "false").Set(2)
4545 gauge.Set(50)
46 gauge.With("test", "true").Set(1)
47 gauge.With("test", "true").Add(1)
4648
4749 client := &bufWriter{}
4850 in.WriteTo(client)
4951
5052 expectedLines := []string{
53 `(influx_gauge,a=b,test=true value=2) [0-9]{19}`,
5154 `(influx_gauge,a=b value=50) [0-9]{19}`,
5255 `(influx_gauge,a=b,error=true value=1) [0-9]{19}`,
5356 `(influx_gauge,a=b,error=false value=2) [0-9]{19}`,
5861 }
5962
6063 // Output:
64 // influx_gauge,a=b,test=true value=2
6165 // influx_gauge,a=b value=50
6266 // influx_gauge,a=b,error=true value=1
6367 // influx_gauge,a=b,error=false value=2
6565 return &Gauge{
6666 name: name,
6767 obs: in.gauges.Observe,
68 add: in.gauges.Add,
6869 }
6970 }
7071
219220 name string
220221 lvs lv.LabelValues
221222 obs observeFunc
223 add observeFunc
222224 }
223225
224226 // With implements metrics.Gauge.
227229 name: g.name,
228230 lvs: g.lvs.With(labelValues...),
229231 obs: g.obs,
232 add: g.add,
230233 }
231234 }
232235
233236 // Set implements metrics.Gauge.
234237 func (g *Gauge) Set(value float64) {
235238 g.obs(g.name, g.lvs, value)
239 }
240
241 // Add implements metrics.Gauge.
242 func (g *Gauge) Add(delta float64) {
243 g.add(g.name, g.lvs, delta)
236244 }
237245
238246 // Histogram is an Influx histrogram. Observations are aggregated into a
1818 // the vector space, and appends the value to the list of observations.
1919 func (s *Space) Observe(name string, lvs LabelValues, value float64) {
2020 s.nodeFor(name).observe(lvs, value)
21 }
22
23 // Add locates the time series identified by the name and label values in
24 // the vector space, and appends the delta to the last value in the list of
25 // observations.
26 func (s *Space) Add(name string, lvs LabelValues, delta float64) {
27 s.nodeFor(name).add(lvs, delta)
2128 }
2229
2330 // Walk traverses the vector space and invokes fn for each non-empty time series
9097 child.observe(tail, value)
9198 }
9299
100 func (n *node) add(lvs LabelValues, delta float64) {
101 n.mtx.Lock()
102 defer n.mtx.Unlock()
103 if len(lvs) == 0 {
104 var value float64
105 if len(n.observations) > 0 {
106 value = last(n.observations) + delta
107 } else {
108 value = delta
109 }
110 n.observations = append(n.observations, value)
111 return
112 }
113 if len(lvs) < 2 {
114 panic("too few LabelValues; programmer error!")
115 }
116 head, tail := pair{lvs[0], lvs[1]}, lvs[2:]
117 if n.children == nil {
118 n.children = map[pair]*node{}
119 }
120 child, ok := n.children[head]
121 if !ok {
122 child = &node{}
123 n.children[head] = child
124 }
125 child.add(tail, delta)
126 }
127
93128 func (n *node) walk(lvs LabelValues, fn func(LabelValues, []float64) bool) bool {
94129 n.mtx.RLock()
95130 defer n.mtx.RUnlock()
103138 }
104139 return true
105140 }
141
142 func last(a []float64) float64 {
143 return a[len(a)-1]
144 }
1111 type Gauge interface {
1212 With(labelValues ...string) Gauge
1313 Set(value float64)
14 Add(delta float64)
1415 }
1516
1617 // Histogram describes a metric that takes repeated observations of the same
5353 return next
5454 }
5555
56 // Add implements metrics.Gauge.
57 func (g Gauge) Add(delta float64) {
58 for _, gauge := range g {
59 gauge.Add(delta)
60 }
61 }
62
5663 // Histogram collects multiple individual histograms and treats them as a unit.
5764 type Histogram []metrics.Histogram
5865
3232 mg.Set(9)
3333 mg.Set(8)
3434 mg.Set(7)
35 mg.Add(3)
3536
36 want := "[9 8 7]"
37 want := "[9 8 7 10]"
3738 for i, m := range []fmt.Stringer{g1, g2, g3} {
3839 if have := m.String(); want != have {
3940 t.Errorf("g%d: want %q, have %q", i+1, want, have)
7576 func (g *mockGauge) Set(value float64) { g.obs = append(g.obs, value) }
7677 func (g *mockGauge) With(...string) metrics.Gauge { return g }
7778 func (g *mockGauge) String() string { return fmt.Sprintf("%v", g.obs) }
79 func (g *mockGauge) Add(delta float64) {
80 var value float64
81 if len(g.obs) > 0 {
82 value = g.obs[len(g.obs)-1] + delta
83 } else {
84 value = delta
85 }
86 g.obs = append(g.obs, value)
87 }
7888
7989 type mockHistogram struct {
8090 obs []float64
8181 func (g *Gauge) Set(value float64) { g.g.Set(value) }
8282
8383 // Add adds a value to the gauge.
84 func (g *Gauge) Add(value float64) { g.g.Inc(value) }
84 func (g *Gauge) Add(delta float64) { g.g.Inc(delta) }
8585
8686 // Histogram wraps a speed Histogram.
8787 type Histogram struct {
7373 return &Gauge{
7474 name: s.prefix + name,
7575 obs: s.gauges.Observe,
76 add: s.gauges.Add,
7677 }
7778 }
7879
200201 type Gauge struct {
201202 name string
202203 obs observeFunc
204 add observeFunc
203205 }
204206
205207 // With is a no-op.
210212 // Set implements metrics.Gauge.
211213 func (g *Gauge) Set(value float64) {
212214 g.obs(g.name, lv.LabelValues{}, value)
215 }
216
217 // Add implements metrics.Gauge.
218 func (g *Gauge) Add(delta float64) {
219 g.add(g.name, lv.LabelValues{}, delta)
213220 }
214221
215222 // Timing is a StatsD timing, or metrics.Histogram. Observations are
4141 f := float64(a[i])
4242 gauge.Set(f)
4343 want = f
44 }
45
46 for i := 0; i < n; i++ {
47 f := float64(a[i])
48 gauge.Add(f)
49 want += f
4450 }
4551
4652 if have := value(); want != have {