[bugfix] Prometheus metrics without warnings

go-metrics is updated to 0.3.6 to properly handle help in prometheus metrics

This fixes https://github.com/hashicorp/consul/issues/9303 and
https://github.com/hashicorp/consul/issues/9471
This commit is contained in:
Pierre Souchay 2021-01-06 13:32:50 +01:00
parent 19baf4bc25
commit 408b249fc5
6 changed files with 53 additions and 30 deletions

3
.changelog/9510.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
client: Help added in Prometheus in relases 1.9.0 does not generate warnings anymore in logs
```

2
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/Microsoft/go-winio v0.4.3 // indirect github.com/Microsoft/go-winio v0.4.3 // indirect
github.com/NYTimes/gziphandler v1.0.1 github.com/NYTimes/gziphandler v1.0.1
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425 github.com/armon/go-metrics v0.3.6
github.com/armon/go-radix v1.0.0 github.com/armon/go-radix v1.0.0
github.com/aws/aws-sdk-go v1.25.41 github.com/aws/aws-sdk-go v1.25.41
github.com/coredns/coredns v1.1.2 github.com/coredns/coredns v1.1.2

4
go.sum
View File

@ -59,8 +59,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425 h1:23nUvGE+8HYFc0AUXuYxgFws6IdyzOrSJJmKfPMJmi8= github.com/armon/go-metrics v0.3.6 h1:x/tmtOF9cDBoXH7XoAGOz2qqm1DknFD1590XmD/DUJ8=
github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.3.6/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=

View File

@ -228,12 +228,12 @@ func (m *Metrics) allowMetric(key []string, labels []Label) (bool, []Label) {
func (m *Metrics) collectStats() { func (m *Metrics) collectStats() {
for { for {
time.Sleep(m.ProfileInterval) time.Sleep(m.ProfileInterval)
m.emitRuntimeStats() m.EmitRuntimeStats()
} }
} }
// Emits various runtime statsitics // Emits various runtime statsitics
func (m *Metrics) emitRuntimeStats() { func (m *Metrics) EmitRuntimeStats() {
// Export number of Goroutines // Export number of Goroutines
numRoutines := runtime.NumGoroutine() numRoutines := runtime.NumGoroutine()
m.SetGauge([]string{"runtime", "num_goroutines"}, float32(numRoutines)) m.SetGauge([]string{"runtime", "num_goroutines"}, float32(numRoutines))

View File

@ -58,13 +58,14 @@ type PrometheusSink struct {
summaries sync.Map summaries sync.Map
counters sync.Map counters sync.Map
expiration time.Duration expiration time.Duration
help map[string]string
} }
// GaugeDefinition can be provided to PrometheusOpts to declare a constant gauge that is not deleted on expiry. // GaugeDefinition can be provided to PrometheusOpts to declare a constant gauge that is not deleted on expiry.
type GaugeDefinition struct { type GaugeDefinition struct {
Name []string Name []string
ConstLabels []metrics.Label ConstLabels []metrics.Label
Help string Help string
} }
type gauge struct { type gauge struct {
@ -76,9 +77,9 @@ type gauge struct {
// SummaryDefinition can be provided to PrometheusOpts to declare a constant summary that is not deleted on expiry. // SummaryDefinition can be provided to PrometheusOpts to declare a constant summary that is not deleted on expiry.
type SummaryDefinition struct { type SummaryDefinition struct {
Name []string Name []string
ConstLabels []metrics.Label ConstLabels []metrics.Label
Help string Help string
} }
type summary struct { type summary struct {
@ -89,9 +90,9 @@ type summary struct {
// CounterDefinition can be provided to PrometheusOpts to declare a constant counter that is not deleted on expiry. // CounterDefinition can be provided to PrometheusOpts to declare a constant counter that is not deleted on expiry.
type CounterDefinition struct { type CounterDefinition struct {
Name []string Name []string
ConstLabels []metrics.Label ConstLabels []metrics.Label
Help string Help string
} }
type counter struct { type counter struct {
@ -112,11 +113,12 @@ func NewPrometheusSinkFrom(opts PrometheusOpts) (*PrometheusSink, error) {
summaries: sync.Map{}, summaries: sync.Map{},
counters: sync.Map{}, counters: sync.Map{},
expiration: opts.Expiration, expiration: opts.Expiration,
help: make(map[string]string),
} }
initGauges(&sink.gauges, opts.GaugeDefinitions) initGauges(&sink.gauges, opts.GaugeDefinitions, sink.help)
initSummaries(&sink.summaries, opts.SummaryDefinitions) initSummaries(&sink.summaries, opts.SummaryDefinitions, sink.help)
initCounters(&sink.counters, opts.CounterDefinitions) initCounters(&sink.counters, opts.CounterDefinitions, sink.help)
reg := opts.Registerer reg := opts.Registerer
if reg == nil { if reg == nil {
@ -191,22 +193,24 @@ func (p *PrometheusSink) Collect(c chan<- prometheus.Metric) {
}) })
} }
func initGauges(m *sync.Map, gauges []GaugeDefinition) { func initGauges(m *sync.Map, gauges []GaugeDefinition, help map[string]string) {
for _, g := range gauges { for _, g := range gauges {
key, hash := flattenKey(g.Name, g.ConstLabels) key, hash := flattenKey(g.Name, g.ConstLabels)
help[fmt.Sprintf("gauge.%s", key)] = g.Help
pG := prometheus.NewGauge(prometheus.GaugeOpts{ pG := prometheus.NewGauge(prometheus.GaugeOpts{
Name: key, Name: key,
Help: g.Help, Help: g.Help,
ConstLabels: prometheusLabels(g.ConstLabels), ConstLabels: prometheusLabels(g.ConstLabels),
}) })
m.Store(hash, &gauge{ Gauge: pG }) m.Store(hash, &gauge{Gauge: pG})
} }
return return
} }
func initSummaries(m *sync.Map, summaries []SummaryDefinition) { func initSummaries(m *sync.Map, summaries []SummaryDefinition, help map[string]string) {
for _, s := range summaries { for _, s := range summaries {
key, hash := flattenKey(s.Name, s.ConstLabels) key, hash := flattenKey(s.Name, s.ConstLabels)
help[fmt.Sprintf("summary.%s", key)] = s.Help
pS := prometheus.NewSummary(prometheus.SummaryOpts{ pS := prometheus.NewSummary(prometheus.SummaryOpts{
Name: key, Name: key,
Help: s.Help, Help: s.Help,
@ -214,20 +218,21 @@ func initSummaries(m *sync.Map, summaries []SummaryDefinition) {
ConstLabels: prometheusLabels(s.ConstLabels), ConstLabels: prometheusLabels(s.ConstLabels),
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
}) })
m.Store(hash, &summary{ Summary: pS }) m.Store(hash, &summary{Summary: pS})
} }
return return
} }
func initCounters(m *sync.Map, counters []CounterDefinition) { func initCounters(m *sync.Map, counters []CounterDefinition, help map[string]string) {
for _, c := range counters { for _, c := range counters {
key, hash := flattenKey(c.Name, c.ConstLabels) key, hash := flattenKey(c.Name, c.ConstLabels)
help[fmt.Sprintf("counter.%s", key)] = c.Help
pC := prometheus.NewCounter(prometheus.CounterOpts{ pC := prometheus.NewCounter(prometheus.CounterOpts{
Name: key, Name: key,
Help: c.Help, Help: c.Help,
ConstLabels: prometheusLabels(c.ConstLabels), ConstLabels: prometheusLabels(c.ConstLabels),
}) })
m.Store(hash, &counter{ Counter: pC }) m.Store(hash, &counter{Counter: pC})
} }
return return
} }
@ -274,16 +279,21 @@ func (p *PrometheusSink) SetGaugeWithLabels(parts []string, val float32, labels
localGauge.updatedAt = time.Now() localGauge.updatedAt = time.Now()
p.gauges.Store(hash, &localGauge) p.gauges.Store(hash, &localGauge)
// The gauge does not exist, create the gauge and allow it to be deleted // The gauge does not exist, create the gauge and allow it to be deleted
} else { } else {
help := key
existingHelp, ok := p.help[fmt.Sprintf("gauge.%s", key)]
if ok {
help = existingHelp
}
g := prometheus.NewGauge(prometheus.GaugeOpts{ g := prometheus.NewGauge(prometheus.GaugeOpts{
Name: key, Name: key,
Help: key, Help: help,
ConstLabels: prometheusLabels(labels), ConstLabels: prometheusLabels(labels),
}) })
g.Set(float64(val)) g.Set(float64(val))
pg = &gauge{ pg = &gauge{
Gauge: g, Gauge: g,
updatedAt: time.Now(), updatedAt: time.Now(),
canDelete: true, canDelete: true,
} }
@ -306,18 +316,23 @@ func (p *PrometheusSink) AddSampleWithLabels(parts []string, val float32, labels
localSummary.updatedAt = time.Now() localSummary.updatedAt = time.Now()
p.summaries.Store(hash, &localSummary) p.summaries.Store(hash, &localSummary)
// The summary does not exist, create the Summary and allow it to be deleted // The summary does not exist, create the Summary and allow it to be deleted
} else { } else {
help := key
existingHelp, ok := p.help[fmt.Sprintf("summary.%s", key)]
if ok {
help = existingHelp
}
s := prometheus.NewSummary(prometheus.SummaryOpts{ s := prometheus.NewSummary(prometheus.SummaryOpts{
Name: key, Name: key,
Help: key, Help: help,
MaxAge: 10 * time.Second, MaxAge: 10 * time.Second,
ConstLabels: prometheusLabels(labels), ConstLabels: prometheusLabels(labels),
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
}) })
s.Observe(float64(val)) s.Observe(float64(val))
ps = &summary{ ps = &summary{
Summary: s, Summary: s,
updatedAt: time.Now(), updatedAt: time.Now(),
canDelete: true, canDelete: true,
} }
@ -346,16 +361,21 @@ func (p *PrometheusSink) IncrCounterWithLabels(parts []string, val float32, labe
localCounter.updatedAt = time.Now() localCounter.updatedAt = time.Now()
p.counters.Store(hash, &localCounter) p.counters.Store(hash, &localCounter)
// The counter does not exist yet, create it and allow it to be deleted // The counter does not exist yet, create it and allow it to be deleted
} else { } else {
help := key
existingHelp, ok := p.help[fmt.Sprintf("counter.%s", key)]
if ok {
help = existingHelp
}
c := prometheus.NewCounter(prometheus.CounterOpts{ c := prometheus.NewCounter(prometheus.CounterOpts{
Name: key, Name: key,
Help: key, Help: help,
ConstLabels: prometheusLabels(labels), ConstLabels: prometheusLabels(labels),
}) })
c.Add(float64(val)) c.Add(float64(val))
pc = &counter{ pc = &counter{
Counter: c, Counter: c,
updatedAt: time.Now(), updatedAt: time.Now(),
canDelete: true, canDelete: true,
} }

2
vendor/modules.txt vendored
View File

@ -32,7 +32,7 @@ github.com/NYTimes/gziphandler
github.com/StackExchange/wmi github.com/StackExchange/wmi
# github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e # github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
github.com/armon/circbuf github.com/armon/circbuf
# github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425 # github.com/armon/go-metrics v0.3.6
github.com/armon/go-metrics github.com/armon/go-metrics
github.com/armon/go-metrics/circonus github.com/armon/go-metrics/circonus
github.com/armon/go-metrics/datadog github.com/armon/go-metrics/datadog