зеркало из https://github.com/github/vitess-gh.git
Get rid of the pull_backend.go
Fix tests to use the new metric names. Fix tests that expected gauges and not counters. (more to come on this thing, but these were the tests that indicated gauges early) Fix the `Set()` implementation for GaugesWithMultiLabels. Signed-off-by: Maggie Zhou <mzhou@slack-corp.com>
This commit is contained in:
Родитель
0d17a264e0
Коммит
f2afcd25d5
|
@ -378,7 +378,8 @@ func (mg *GaugesWithMultiLabels) Set(names []string, value int64) {
|
|||
if len(names) != len(mg.CountersWithMultiLabels.labels) {
|
||||
panic("GaugesWithMultiLabels: wrong number of values in Set")
|
||||
}
|
||||
mg.CountersWithMultiLabels.Counters.Add(mapKey(names), value)
|
||||
a := mg.getValueAddr(mapKey(names))
|
||||
atomic.StoreInt64(a, value)
|
||||
}
|
||||
|
||||
// CountersFuncWithMultiLabels is a multidimensional CountersFunc implementation
|
||||
|
|
|
@ -56,14 +56,14 @@ func TestCounters(t *testing.T) {
|
|||
|
||||
func TestCountersTags(t *testing.T) {
|
||||
clear()
|
||||
c := NewCountersWithLabels("counterTag1", "help")
|
||||
c := NewCountersWithLabels("counterTag1", "help", "label")
|
||||
want := map[string]int64{}
|
||||
got := c.Counts()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("want %v, got %v", want, got)
|
||||
}
|
||||
|
||||
c = NewCountersWithLabels("counterTag2", "help", "tag1", "tag2")
|
||||
c = NewCountersWithLabels("counterTag2", "help", "label", "tag1", "tag2")
|
||||
want = map[string]int64{"tag1": 0, "tag2": 0}
|
||||
got = c.Counts()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
|
@ -73,7 +73,7 @@ func TestCountersTags(t *testing.T) {
|
|||
|
||||
func TestMultiCounters(t *testing.T) {
|
||||
clear()
|
||||
c := NewMultiCounters("mapCounter1", "help", []string{"aaa", "bbb"})
|
||||
c := NewCountersWithMultiLabels("mapCounter1", "help", []string{"aaa", "bbb"})
|
||||
c.Add([]string{"c1a", "c1b"}, 1)
|
||||
c.Add([]string{"c2a", "c2b"}, 1)
|
||||
c.Add([]string{"c2a", "c2b"}, 1)
|
||||
|
@ -89,7 +89,7 @@ func TestMultiCounters(t *testing.T) {
|
|||
if counts["c2a.c2b"] != 2 {
|
||||
t.Errorf("want 2, got %d", counts["c2a.c2b"])
|
||||
}
|
||||
f := NewMultiCountersFunc("", []string{"aaa", "bbb"}, "help", func() map[string]int64 {
|
||||
f := NewCountersFuncWithMultiLabels("", []string{"aaa", "bbb"}, "help", func() map[string]int64 {
|
||||
return map[string]int64{
|
||||
"c1a.c1b": 1,
|
||||
"c2a.c2b": 2,
|
||||
|
@ -102,7 +102,7 @@ func TestMultiCounters(t *testing.T) {
|
|||
|
||||
func TestMultiCountersDot(t *testing.T) {
|
||||
clear()
|
||||
c := NewMultiCounters("mapCounter2", "help", []string{"aaa", "bbb"})
|
||||
c := NewCountersWithMultiLabels("mapCounter2", "help", []string{"aaa", "bbb"})
|
||||
c.Add([]string{"c1.a", "c1b"}, 1)
|
||||
c.Add([]string{"c2a", "c2.b"}, 1)
|
||||
c.Add([]string{"c2a", "c2.b"}, 1)
|
||||
|
@ -122,11 +122,11 @@ func TestMultiCountersDot(t *testing.T) {
|
|||
|
||||
func TestCountersHook(t *testing.T) {
|
||||
var gotname string
|
||||
var gotv *Counters
|
||||
var gotv *CountersWithLabels
|
||||
clear()
|
||||
Register(func(name string, v expvar.Var) {
|
||||
gotname = name
|
||||
gotv = v.(*Counters)
|
||||
gotv = v.(*CountersWithLabels)
|
||||
})
|
||||
|
||||
v := NewCountersWithLabels("counter2", "help", "type")
|
||||
|
@ -152,7 +152,7 @@ func BenchmarkCounters(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
var benchMultiCounter = NewMultiCounters("benchMulti", "help", []string{"call", "keyspace", "dbtype"})
|
||||
var benchMultiCounter = NewCountersWithMultiLabels("benchMulti", "help", []string{"call", "keyspace", "dbtype"})
|
||||
|
||||
func BenchmarkMultiCounters(b *testing.B) {
|
||||
clear()
|
||||
|
|
|
@ -29,7 +29,7 @@ func clear() {
|
|||
|
||||
func TestNoHook(t *testing.T) {
|
||||
clear()
|
||||
v := NewInt("plainint", "help")
|
||||
v := NewCounter("plainint", "help")
|
||||
v.Add(1)
|
||||
if v.String() != "1" {
|
||||
t.Errorf("want 1, got %s", v.String())
|
||||
|
@ -71,15 +71,15 @@ func TestFloat(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInt(t *testing.T) {
|
||||
func TestCounter(t *testing.T) {
|
||||
var gotname string
|
||||
var gotv *Int
|
||||
var gotv *Counter
|
||||
clear()
|
||||
Register(func(name string, v expvar.Var) {
|
||||
gotname = name
|
||||
gotv = v.(*Int)
|
||||
gotv = v.(*Counter)
|
||||
})
|
||||
v := NewInt("Int", "help")
|
||||
v := NewCounter("Int", "help")
|
||||
if gotname != "Int" {
|
||||
t.Errorf("want Int, got %s", gotname)
|
||||
}
|
||||
|
@ -98,11 +98,22 @@ func TestInt(t *testing.T) {
|
|||
t.Errorf("want 0, got %v", v.Get())
|
||||
}
|
||||
|
||||
f := NewIntFunc("name", "help", func() int64 {
|
||||
}
|
||||
|
||||
func TestGaugeFunc(t *testing.T) {
|
||||
var gotname string
|
||||
var gotv *GaugeFunc
|
||||
clear()
|
||||
Register(func(name string, v expvar.Var) {
|
||||
gotname = name
|
||||
gotv = v.(*GaugeFunc)
|
||||
})
|
||||
|
||||
f := NewGaugeFunc("name", "help", func() int64 {
|
||||
return 1
|
||||
})
|
||||
if f.String() != "1" {
|
||||
t.Errorf("want 1, got %v", f.String())
|
||||
t.Errorf("want 1, got %f", f.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,141 +9,123 @@ import (
|
|||
|
||||
// metricsCollector collects both stats.Counters and stats.Gauges
|
||||
type metricsCollector struct {
|
||||
counters map[*stats.Counters]*prom.Desc
|
||||
vt stats.ValueType
|
||||
counter *stats.Counters
|
||||
desc *prom.Desc
|
||||
vt ValueType
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *metricsCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.counters {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *metricsCollector) Collect(ch chan<- prom.Metric) {
|
||||
for counter, desc := range c.counters {
|
||||
for tag, val := range counter.Counts() {
|
||||
ch <- prom.MustNewConstMetric(
|
||||
desc,
|
||||
toPromValueType(c.vt),
|
||||
float64(val),
|
||||
tag)
|
||||
}
|
||||
for tag, val := range c.counter.Counts() {
|
||||
ch <- prom.MustNewConstMetric(
|
||||
c.desc,
|
||||
toPromValueType(c.vt),
|
||||
float64(val),
|
||||
tag)
|
||||
}
|
||||
}
|
||||
|
||||
type multiCountersCollector struct {
|
||||
multiCounters map[*stats.CountersWithMultiLabels]*prom.Desc
|
||||
cml *stats.CountersWithMultiLabels
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *multiCountersCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.multiCounters {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *multiCountersCollector) Collect(ch chan<- prom.Metric) {
|
||||
for mc, desc := range c.multiCounters {
|
||||
for lvs, val := range mc.Counters.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(desc, prom.CounterValue, value, labelValues...)
|
||||
}
|
||||
for lvs, val := range c.cml.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(c.desc, prom.CounterValue, value, labelValues...)
|
||||
}
|
||||
}
|
||||
|
||||
type multiGaugesCollector struct {
|
||||
multiGauges map[*stats.GaugesWithMultiLabels]*prom.Desc
|
||||
gml *stats.GaugesWithMultiLabels
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *multiGaugesCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.multiGauges {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *multiGaugesCollector) Collect(ch chan<- prom.Metric) {
|
||||
for mc, desc := range c.multiGauges {
|
||||
for lvs, val := range mc.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(desc, prom.GaugeValue, value, labelValues...)
|
||||
}
|
||||
for lvs, val := range c.gml.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(c.desc, prom.GaugeValue, value, labelValues...)
|
||||
}
|
||||
}
|
||||
|
||||
type multiCountersFuncCollector struct {
|
||||
multiCountersFunc map[*stats.CountersFuncWithMultiLabels]*prom.Desc
|
||||
cfml *stats.CountersFuncWithMultiLabels
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *multiCountersFuncCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.multiCountersFunc {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *multiCountersFuncCollector) Collect(ch chan<- prom.Metric) {
|
||||
for mcf, desc := range c.multiCountersFunc {
|
||||
for lvs, val := range mcf.CountersFunc.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(desc, prom.CounterValue, value, labelValues...)
|
||||
}
|
||||
for lvs, val := range c.cfml.Counts() {
|
||||
labelValues := strings.Split(lvs, ".")
|
||||
value := float64(val)
|
||||
ch <- prom.MustNewConstMetric(c.desc, prom.CounterValue, value, labelValues...)
|
||||
}
|
||||
}
|
||||
|
||||
type metricCollector struct {
|
||||
m map[*stats.Counter]*prom.Desc
|
||||
vt stats.ValueType
|
||||
counter *stats.Counter
|
||||
desc *prom.Desc
|
||||
vt ValueType
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *metricCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.m {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *metricCollector) Collect(ch chan<- prom.Metric) {
|
||||
for i, desc := range c.m {
|
||||
val := i.Get()
|
||||
if i.Get() == 0 {
|
||||
val = 1
|
||||
}
|
||||
ch <- prom.MustNewConstMetric(desc, toPromValueType(c.vt), float64(val))
|
||||
val := c.counter.Get()
|
||||
if c.counter.Get() == 0 {
|
||||
val = 1
|
||||
}
|
||||
ch <- prom.MustNewConstMetric(c.desc, toPromValueType(c.vt), float64(val))
|
||||
}
|
||||
|
||||
type timingsCollector struct {
|
||||
timings map[*stats.Timings]*prom.Desc
|
||||
t *stats.Timings
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *timingsCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.timings {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *timingsCollector) Collect(ch chan<- prom.Metric) {
|
||||
for t, desc := range c.timings {
|
||||
for cat, his := range t.Histograms() {
|
||||
ch <- prom.MustNewConstHistogram(
|
||||
desc,
|
||||
uint64(his.Count()),
|
||||
float64(his.Total()),
|
||||
makePromBucket(his.Cutoffs(), his.Buckets()),
|
||||
cat)
|
||||
}
|
||||
for cat, his := range c.t.Histograms() {
|
||||
ch <- prom.MustNewConstHistogram(
|
||||
c.desc,
|
||||
uint64(his.Count()),
|
||||
float64(his.Total()),
|
||||
makePromBucket(his.Cutoffs(), his.Buckets()),
|
||||
cat)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,53 +142,47 @@ func makePromBucket(cutoffs []int64, buckets []int64) map[float64]uint64 {
|
|||
}
|
||||
|
||||
type multiTimingsCollector struct {
|
||||
multiTimings map[*stats.MultiTimings]*prom.Desc
|
||||
mt *stats.MultiTimings
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *multiTimingsCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.multiTimings {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *multiTimingsCollector) Collect(ch chan<- prom.Metric) {
|
||||
for t, desc := range c.multiTimings {
|
||||
for cat, his := range t.Timings.Histograms() {
|
||||
labelValues := strings.Split(cat, ".")
|
||||
ch <- prom.MustNewConstHistogram(
|
||||
desc,
|
||||
uint64(his.Count()),
|
||||
float64(his.Total()),
|
||||
makePromBucket(his.Cutoffs(), his.Buckets()),
|
||||
labelValues...)
|
||||
}
|
||||
for cat, his := range c.mt.Timings.Histograms() {
|
||||
labelValues := strings.Split(cat, ".")
|
||||
ch <- prom.MustNewConstHistogram(
|
||||
c.desc,
|
||||
uint64(his.Count()),
|
||||
float64(his.Total()),
|
||||
makePromBucket(his.Cutoffs(), his.Buckets()),
|
||||
labelValues...)
|
||||
}
|
||||
}
|
||||
|
||||
type gaugeFuncCollector struct {
|
||||
gfm map[*stats.GaugeFunc]*prom.Desc
|
||||
gf *stats.GaugeFunc
|
||||
desc *prom.Desc
|
||||
}
|
||||
|
||||
// Describe implements Collector.
|
||||
func (c *gaugeFuncCollector) Describe(ch chan<- *prom.Desc) {
|
||||
for _, desc := range c.gfm {
|
||||
ch <- desc
|
||||
}
|
||||
ch <- c.desc
|
||||
}
|
||||
|
||||
// Collect implements Collector.
|
||||
func (c *gaugeFuncCollector) Collect(ch chan<- prom.Metric) {
|
||||
for i, desc := range c.gfm {
|
||||
ch <- prom.MustNewConstMetric(desc, prom.GaugeValue, float64(i.F()))
|
||||
}
|
||||
ch <- prom.MustNewConstMetric(c.desc, prom.GaugeValue, float64(c.gf.F()))
|
||||
}
|
||||
|
||||
func toPromValueType(vt stats.ValueType) prom.ValueType {
|
||||
if vt == stats.CounterValue {
|
||||
func toPromValueType(vt ValueType) prom.ValueType {
|
||||
if vt == CounterValue {
|
||||
return prom.CounterValue
|
||||
} else if vt == stats.GaugeValue {
|
||||
} else if vt == GaugeValue {
|
||||
return prom.GaugeValue
|
||||
} else {
|
||||
return prom.UntypedValue
|
||||
|
|
|
@ -29,141 +29,146 @@ func Init(namespace string) {
|
|||
stats.Register(be.PublishPromMetric)
|
||||
}
|
||||
|
||||
// ValueType specifies whether the value of a metric goes up monotonically
|
||||
// or if it goes up and down. This is useful for exporting to backends that
|
||||
// differentiate between counters and gauges.
|
||||
type ValueType int
|
||||
|
||||
const (
|
||||
// CounterValue is used to specify a value that only goes up (but can be reset to 0).
|
||||
CounterValue = iota
|
||||
// GaugeValue is used to specify a value that goes both up adn down.
|
||||
GaugeValue
|
||||
)
|
||||
|
||||
// PublishPromMetric is used to publish the metric to Prometheus.
|
||||
func (be *PromBackend) PublishPromMetric(name string, v expvar.Var) {
|
||||
switch st := v.(type) {
|
||||
case *stats.Counter:
|
||||
be.NewMetric(st, name, stats.CounterValue)
|
||||
be.newMetric(st, name, CounterValue)
|
||||
case *stats.Gauge:
|
||||
be.NewMetric(&st.Counter, name, stats.GaugeValue)
|
||||
be.newMetric(&st.Counter, name, GaugeValue)
|
||||
case *stats.GaugeFunc:
|
||||
be.NewGaugeFunc(st, name)
|
||||
be.newGaugeFunc(st, name)
|
||||
case *stats.CountersWithLabels:
|
||||
be.NewMetricWithLabels(&st.Counters, name, st.LabelName(), stats.CounterValue)
|
||||
be.newMetricWithLabels(&st.Counters, name, st.LabelName(), CounterValue)
|
||||
case *stats.CountersWithMultiLabels:
|
||||
be.NewCountersWithMultiLabels(st, name)
|
||||
be.newCountersWithMultiLabels(st, name)
|
||||
case *stats.CountersFuncWithMultiLabels:
|
||||
be.NewCountersFuncWithMultiLabels(st, name)
|
||||
be.newCountersFuncWithMultiLabels(st, name)
|
||||
case *stats.GaugesWithLabels:
|
||||
be.NewMetricWithLabels(&st.Counters, name, st.LabelName(), stats.GaugeValue)
|
||||
be.newMetricWithLabels(&st.Counters, name, st.LabelName(), GaugeValue)
|
||||
case *stats.GaugesWithMultiLabels:
|
||||
be.NewGaugesWithMultiLabels(st, name)
|
||||
be.newGaugesWithMultiLabels(st, name)
|
||||
case *stats.Timings:
|
||||
be.NewTiming(st, name)
|
||||
be.newTiming(st, name)
|
||||
case *stats.MultiTimings:
|
||||
be.NewMultiTiming(st, name)
|
||||
be.newMultiTiming(st, name)
|
||||
default:
|
||||
log.Warningf("Unsupported type for %s: %T", name, st)
|
||||
}
|
||||
}
|
||||
|
||||
// NewMetricWithLabels is part of the PullBackend interface.
|
||||
func (be *PromBackend) NewMetricWithLabels(c *stats.Counters, name string, labelName string, vt stats.ValueType) {
|
||||
func (be *PromBackend) newMetricWithLabels(c *stats.Counters, name string, labelName string, vt ValueType) {
|
||||
collector := &metricsCollector{
|
||||
counters: map[*stats.Counters]*prom.Desc{
|
||||
c: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
c.Help(),
|
||||
[]string{labelName},
|
||||
nil),
|
||||
}, vt: vt}
|
||||
counter: c,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
c.Help(),
|
||||
[]string{labelName},
|
||||
nil),
|
||||
vt: vt}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
||||
// NewCountersWithMultiLabels is part of the PullBackend interface.
|
||||
func (be *PromBackend) NewCountersWithMultiLabels(mc *stats.CountersWithMultiLabels, name string) {
|
||||
func (be *PromBackend) newCountersWithMultiLabels(cml *stats.CountersWithMultiLabels, name string) {
|
||||
c := &multiCountersCollector{
|
||||
multiCounters: map[*stats.CountersWithMultiLabels]*prom.Desc{
|
||||
mc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
mc.Counters.Help(),
|
||||
labelsToSnake(mc.Labels()),
|
||||
nil),
|
||||
}}
|
||||
cml: cml,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
cml.Counters.Help(),
|
||||
labelsToSnake(cml.Labels()),
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(c)
|
||||
}
|
||||
|
||||
// NewGaugesWithMultiLabels is part of the PullBackend interface.
|
||||
func (be *PromBackend) NewGaugesWithMultiLabels(mg *stats.GaugesWithMultiLabels, name string) {
|
||||
func (be *PromBackend) newGaugesWithMultiLabels(gml *stats.GaugesWithMultiLabels, name string) {
|
||||
c := &multiGaugesCollector{
|
||||
multiGauges: map[*stats.GaugesWithMultiLabels]*prom.Desc{
|
||||
mg: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
mg.Help(),
|
||||
labelsToSnake(mg.Labels()),
|
||||
nil),
|
||||
}}
|
||||
gml: gml,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
gml.Help(),
|
||||
labelsToSnake(gml.Labels()),
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(c)
|
||||
}
|
||||
|
||||
// NewCountersFuncWithMultiLabels is part of the PullBackend interface.
|
||||
func (be *PromBackend) NewCountersFuncWithMultiLabels(mcf *stats.CountersFuncWithMultiLabels, name string) {
|
||||
func (be *PromBackend) newCountersFuncWithMultiLabels(cfml *stats.CountersFuncWithMultiLabels, name string) {
|
||||
collector := &multiCountersFuncCollector{
|
||||
multiCountersFunc: map[*stats.CountersFuncWithMultiLabels]*prom.Desc{
|
||||
mcf: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
mcf.Help(),
|
||||
labelsToSnake(mcf.Labels()),
|
||||
nil),
|
||||
}}
|
||||
cfml: cfml,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
cfml.Help(),
|
||||
labelsToSnake(cfml.Labels()),
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
||||
// NewTiming is part of the PullBackend interface
|
||||
func (be *PromBackend) NewTiming(t *stats.Timings, name string) {
|
||||
func (be *PromBackend) newTiming(t *stats.Timings, name string) {
|
||||
collector := &timingsCollector{
|
||||
timings: map[*stats.Timings]*prom.Desc{
|
||||
t: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
t.Help(),
|
||||
[]string{"Histograms"}, // hard coded label key
|
||||
nil),
|
||||
}}
|
||||
t: t,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
t.Help(),
|
||||
[]string{"Histograms"}, // hard coded label key
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
||||
// NewMultiTiming is part of the PullBackend interface
|
||||
func (be *PromBackend) NewMultiTiming(mt *stats.MultiTimings, name string) {
|
||||
func (be *PromBackend) newMultiTiming(mt *stats.MultiTimings, name string) {
|
||||
collector := &multiTimingsCollector{
|
||||
multiTimings: map[*stats.MultiTimings]*prom.Desc{
|
||||
mt: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
mt.Help(),
|
||||
labelsToSnake(mt.Labels()),
|
||||
nil),
|
||||
}}
|
||||
mt: mt,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
mt.Help(),
|
||||
labelsToSnake(mt.Labels()),
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
||||
// NewMetric is part of the PullBackend interface
|
||||
func (be *PromBackend) NewMetric(c *stats.Counter, name string, vt stats.ValueType) {
|
||||
func (be *PromBackend) newMetric(c *stats.Counter, name string, vt ValueType) {
|
||||
collector := &metricCollector{
|
||||
m: map[*stats.Counter]*prom.Desc{
|
||||
c: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
c.Help(),
|
||||
nil,
|
||||
nil),
|
||||
}, vt: vt}
|
||||
counter: c,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
c.Help(),
|
||||
nil,
|
||||
nil),
|
||||
vt: vt}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
||||
// NewGaugeFunc is part of the PullBackend interface
|
||||
func (be *PromBackend) NewGaugeFunc(gf *stats.GaugeFunc, name string) {
|
||||
func (be *PromBackend) newGaugeFunc(gf *stats.GaugeFunc, name string) {
|
||||
collector := &gaugeFuncCollector{
|
||||
gfm: map[*stats.GaugeFunc]*prom.Desc{
|
||||
gf: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
gf.Help(),
|
||||
nil,
|
||||
nil),
|
||||
}}
|
||||
gf: gf,
|
||||
desc: prom.NewDesc(
|
||||
prom.BuildFQName("", be.namespace, toSnake(name)),
|
||||
gf.Help(),
|
||||
nil,
|
||||
nil),
|
||||
}
|
||||
|
||||
prom.MustRegister(collector)
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
package stats
|
||||
|
||||
// PullBackend should be implemented to export pull metrics from Vitess.
|
||||
// Note that there are no functions implemented to export:
|
||||
// String/StringMap as Prometheus doesn't have support for exporting metrics of those types. Future implementations could add support for that, though, if relevant to the backend.
|
||||
type PullBackend interface {
|
||||
NewMetric(*Counter, string, ValueType)
|
||||
NewMetricWithLabels(*Counters, string, string, ValueType)
|
||||
NewCountersWithMultiLabels(*CountersWithMultiLabels, string)
|
||||
NewCountersFuncWithMultiLabels(*CountersFuncWithMultiLabels, string) // MultiCounterFuncs are always exported as Gauges? Should they just be gauges then.
|
||||
NewGaugesWithMultiLabels(*GaugesWithMultiLabels, string)
|
||||
NewGaugeFunc(*GaugeFunc, string)
|
||||
NewTiming(*Timings, string)
|
||||
NewMultiTiming(*MultiTimings, string)
|
||||
}
|
||||
|
||||
// ValueType specifies whether the value of a metric goes up monotonically
|
||||
// or if it goes up and down. This is useful for exporting to backends that
|
||||
// differentiate between counters and gauges.
|
||||
type ValueType int
|
||||
|
||||
const (
|
||||
// CounterValue is used to specify a value that only goes up (but can be reset to 0).
|
||||
CounterValue = iota
|
||||
// GaugeValue is used to specify a value that goes both up adn down.
|
||||
GaugeValue
|
||||
)
|
|
@ -51,13 +51,13 @@ func TestVariablesAreInitialized(t *testing.T) {
|
|||
statsKey := []string{"init_test", "0"}
|
||||
type testCase struct {
|
||||
desc string
|
||||
counter *stats.MultiCounters
|
||||
counter *stats.CountersWithMultiLabels
|
||||
statsKey []string
|
||||
}
|
||||
testCases := []testCase{
|
||||
{"starts", starts, statsKey},
|
||||
{"failoverDurationSumMs", failoverDurationSumMs, statsKey},
|
||||
{"utilizationSum", utilizationSum, statsKey},
|
||||
{"utilizationSum", &utilizationSum.CountersWithMultiLabels, statsKey},
|
||||
{"utilizationDryRunSum", utilizationDryRunSum, statsKey},
|
||||
{"requestsBuffered", requestsBuffered, statsKey},
|
||||
{"requestsBufferedDryRun", requestsBufferedDryRun, statsKey},
|
||||
|
@ -85,7 +85,7 @@ func TestVariablesAreInitialized(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func checkEntry(counters *stats.MultiCounters, statsKey []string, want int) error {
|
||||
func checkEntry(counters *stats.CountersWithMultiLabels, statsKey []string, want int) error {
|
||||
name := strings.Join(statsKey, ".")
|
||||
got, ok := counters.Counts()[name]
|
||||
if !ok {
|
||||
|
|
|
@ -49,9 +49,9 @@ func TestReaderReadHeartbeat(t *testing.T) {
|
|||
}},
|
||||
})
|
||||
|
||||
cumulativeLagNs.Set(0)
|
||||
readErrors.Set(0)
|
||||
reads.Set(0)
|
||||
cumulativeLagNs.Reset()
|
||||
readErrors.Reset()
|
||||
reads.Reset()
|
||||
|
||||
tr.readHeartbeat()
|
||||
lag, err := tr.GetLatest()
|
||||
|
@ -81,8 +81,8 @@ func TestReaderReadHeartbeatError(t *testing.T) {
|
|||
tr := newReader(db, mockNowFunc)
|
||||
defer tr.Close()
|
||||
|
||||
cumulativeLagNs.Set(0)
|
||||
readErrors.Set(0)
|
||||
cumulativeLagNs.Reset()
|
||||
readErrors.Reset()
|
||||
|
||||
tr.readHeartbeat()
|
||||
lag, err := tr.GetLatest()
|
||||
|
|
|
@ -46,7 +46,7 @@ func TestCreateSchema(t *testing.T) {
|
|||
defer db.Close()
|
||||
tw := newTestWriter(db, mockNowFunc)
|
||||
defer tw.Close()
|
||||
writes.Set(0)
|
||||
writes.Reset()
|
||||
|
||||
db.AddQuery(sqlTurnoffBinlog, &sqltypes.Result{})
|
||||
db.AddQuery(fmt.Sprintf(sqlCreateHeartbeatTable, tw.dbName), &sqltypes.Result{})
|
||||
|
@ -74,8 +74,8 @@ func TestWriteHeartbeat(t *testing.T) {
|
|||
tw := newTestWriter(db, mockNowFunc)
|
||||
db.AddQuery(fmt.Sprintf("UPDATE %s.heartbeat SET ts=%d, tabletUid=%d WHERE keyspaceShard='%s'", tw.dbName, now.UnixNano(), tw.tabletAlias.Uid, tw.keyspaceShard), &sqltypes.Result{})
|
||||
|
||||
writes.Set(0)
|
||||
writeErrors.Set(0)
|
||||
writes.Reset()
|
||||
writeErrors.Reset()
|
||||
|
||||
tw.writeHeartbeat()
|
||||
if got, want := writes.Get(), int64(1); got != want {
|
||||
|
@ -93,8 +93,8 @@ func TestWriteHeartbeatError(t *testing.T) {
|
|||
|
||||
tw := newTestWriter(db, mockNowFunc)
|
||||
|
||||
writes.Set(0)
|
||||
writeErrors.Set(0)
|
||||
writes.Reset()
|
||||
writeErrors.Reset()
|
||||
|
||||
tw.writeHeartbeat()
|
||||
if got, want := writes.Get(), int64(0); got != want {
|
||||
|
|
|
@ -38,8 +38,8 @@ func resetVariables() {
|
|||
waitsDryRun.Reset()
|
||||
queueExceeded.Reset()
|
||||
queueExceededDryRun.Reset()
|
||||
globalQueueExceeded.Set(0)
|
||||
globalQueueExceededDryRun.Set(0)
|
||||
globalQueueExceeded.Reset()
|
||||
globalQueueExceededDryRun.Reset()
|
||||
}
|
||||
|
||||
func TestTxSerializer_NoHotRow(t *testing.T) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче