Codebase list golang-github-go-kit-kit / 160de2f
Reimplement package multi Peter Bourgon 7 years ago
2 changed file(s) with 165 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 // Package multi provides adapters that send observations to multiple metrics
1 // simultaneously. This is useful if your service needs to emit to multiple
2 // instrumentation systems at the same time, for example if your organization is
3 // transitioning from one system to another.
4 package multi
5
6 import "github.com/go-kit/kit/metrics"
7
8 // Counter collects multiple individual counters and treats them as a unit.
9 type Counter []metrics.Counter
10
11 // NewCounter returns a multi-counter, wrapping the passed counters.
12 func NewCounter(c ...metrics.Counter) Counter {
13 return Counter(c)
14 }
15
16 // Add implements counter.
17 func (c Counter) Add(delta float64) {
18 for _, counter := range c {
19 counter.Add(delta)
20 }
21 }
22
23 // With implements counter.
24 func (c Counter) With(labelValues ...string) metrics.Counter {
25 next := make(Counter, len(c))
26 for i := range c {
27 next[i] = c[i].With(labelValues...)
28 }
29 return next
30 }
31
32 // Gauge collects multiple individual gauges and treats them as a unit.
33 type Gauge []metrics.Gauge
34
35 // NewGauge returns a multi-gauge, wrapping the passed gauges.
36 func NewGauge(g ...metrics.Gauge) Gauge {
37 return Gauge(g)
38 }
39
40 // Set implements Gauge.
41 func (g Gauge) Set(value float64) {
42 for _, gauge := range g {
43 gauge.Set(value)
44 }
45 }
46
47 // With implements gauge.
48 func (g Gauge) With(labelValues ...string) metrics.Gauge {
49 next := make(Gauge, len(g))
50 for i := range g {
51 next[i] = g[i].With(labelValues...)
52 }
53 return next
54 }
55
56 // Histogram collects multiple individual histograms and treats them as a unit.
57 type Histogram []metrics.Histogram
58
59 // NewHistogram returns a multi-histogram, wrapping the passed histograms.
60 func NewHistogram(h ...metrics.Histogram) Histogram {
61 return Histogram(h)
62 }
63
64 // Observe implements Histogram.
65 func (h Histogram) Observe(value float64) {
66 for _, histogram := range h {
67 histogram.Observe(value)
68 }
69 }
70
71 // With implements histogram.
72 func (h Histogram) With(labelValues ...string) metrics.Histogram {
73 next := make(Histogram, len(h))
74 for i := range h {
75 next[i] = h[i].With(labelValues...)
76 }
77 return next
78 }
0 package multi
1
2 import (
3 "fmt"
4 "testing"
5
6 "github.com/go-kit/kit/metrics"
7 )
8
9 func TestMultiCounter(t *testing.T) {
10 c1 := &mockCounter{}
11 c2 := &mockCounter{}
12 c3 := &mockCounter{}
13 mc := NewCounter(c1, c2, c3)
14
15 mc.Add(123)
16 mc.Add(456)
17
18 want := "[123 456]"
19 for i, m := range []fmt.Stringer{c1, c2, c3} {
20 if have := m.String(); want != have {
21 t.Errorf("c%d: want %q, have %q", i+1, want, have)
22 }
23 }
24 }
25
26 func TestMultiGauge(t *testing.T) {
27 g1 := &mockGauge{}
28 g2 := &mockGauge{}
29 g3 := &mockGauge{}
30 mg := NewGauge(g1, g2, g3)
31
32 mg.Set(9)
33 mg.Set(8)
34 mg.Set(7)
35
36 want := "[9 8 7]"
37 for i, m := range []fmt.Stringer{g1, g2, g3} {
38 if have := m.String(); want != have {
39 t.Errorf("g%d: want %q, have %q", i+1, want, have)
40 }
41 }
42 }
43
44 func TestMultiHistogram(t *testing.T) {
45 h1 := &mockHistogram{}
46 h2 := &mockHistogram{}
47 h3 := &mockHistogram{}
48 mh := NewHistogram(h1, h2, h3)
49
50 mh.Observe(1)
51 mh.Observe(2)
52 mh.Observe(4)
53 mh.Observe(8)
54
55 want := "[1 2 4 8]"
56 for i, m := range []fmt.Stringer{h1, h2, h3} {
57 if have := m.String(); want != have {
58 t.Errorf("g%d: want %q, have %q", i+1, want, have)
59 }
60 }
61 }
62
63 type mockCounter struct {
64 obs []float64
65 }
66
67 func (c *mockCounter) Add(delta float64) { c.obs = append(c.obs, delta) }
68 func (c *mockCounter) With(...string) metrics.Counter { return c }
69 func (c *mockCounter) String() string { return fmt.Sprintf("%v", c.obs) }
70
71 type mockGauge struct {
72 obs []float64
73 }
74
75 func (g *mockGauge) Set(value float64) { g.obs = append(g.obs, value) }
76 func (g *mockGauge) With(...string) metrics.Gauge { return g }
77 func (g *mockGauge) String() string { return fmt.Sprintf("%v", g.obs) }
78
79 type mockHistogram struct {
80 obs []float64
81 }
82
83 func (h *mockHistogram) Observe(value float64) { h.obs = append(h.obs, value) }
84 func (h *mockHistogram) With(...string) metrics.Histogram { return h }
85 func (h *mockHistogram) String() string { return fmt.Sprintf("%v", h.obs) }