mirror of
https://github.com/prometheus/statsd_exporter.git
synced 2024-12-23 22:10:30 +00:00
Merge pull request #72 from jacksontj/master
Fixes for crashes with conflicting metric values
This commit is contained in:
commit
8b40f781ef
2 changed files with 50 additions and 27 deletions
51
exporter.go
51
exporter.go
|
@ -69,7 +69,7 @@ func NewCounterContainer() *CounterContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CounterContainer) Get(metricName string, labels prometheus.Labels) prometheus.Counter {
|
func (c *CounterContainer) Get(metricName string, labels prometheus.Labels) (prometheus.Counter, error) {
|
||||||
hash := hashNameAndLabels(metricName, labels)
|
hash := hashNameAndLabels(metricName, labels)
|
||||||
counter, ok := c.Elements[hash]
|
counter, ok := c.Elements[hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -78,12 +78,12 @@ func (c *CounterContainer) Get(metricName string, labels prometheus.Labels) prom
|
||||||
Help: defaultHelp,
|
Help: defaultHelp,
|
||||||
ConstLabels: labels,
|
ConstLabels: labels,
|
||||||
})
|
})
|
||||||
c.Elements[hash] = counter
|
|
||||||
if err := prometheus.Register(counter); err != nil {
|
if err := prometheus.Register(counter); err != nil {
|
||||||
log.Fatalf(regErrF, metricName, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.Elements[hash] = counter
|
||||||
}
|
}
|
||||||
return counter
|
return counter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type GaugeContainer struct {
|
type GaugeContainer struct {
|
||||||
|
@ -96,7 +96,7 @@ func NewGaugeContainer() *GaugeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GaugeContainer) Get(metricName string, labels prometheus.Labels) prometheus.Gauge {
|
func (c *GaugeContainer) Get(metricName string, labels prometheus.Labels) (prometheus.Gauge, error) {
|
||||||
hash := hashNameAndLabels(metricName, labels)
|
hash := hashNameAndLabels(metricName, labels)
|
||||||
gauge, ok := c.Elements[hash]
|
gauge, ok := c.Elements[hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -105,12 +105,12 @@ func (c *GaugeContainer) Get(metricName string, labels prometheus.Labels) promet
|
||||||
Help: defaultHelp,
|
Help: defaultHelp,
|
||||||
ConstLabels: labels,
|
ConstLabels: labels,
|
||||||
})
|
})
|
||||||
c.Elements[hash] = gauge
|
|
||||||
if err := prometheus.Register(gauge); err != nil {
|
if err := prometheus.Register(gauge); err != nil {
|
||||||
log.Fatalf(regErrF, metricName, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.Elements[hash] = gauge
|
||||||
}
|
}
|
||||||
return gauge
|
return gauge, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SummaryContainer struct {
|
type SummaryContainer struct {
|
||||||
|
@ -123,7 +123,7 @@ func NewSummaryContainer() *SummaryContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SummaryContainer) Get(metricName string, labels prometheus.Labels) prometheus.Summary {
|
func (c *SummaryContainer) Get(metricName string, labels prometheus.Labels) (prometheus.Summary, error) {
|
||||||
hash := hashNameAndLabels(metricName, labels)
|
hash := hashNameAndLabels(metricName, labels)
|
||||||
summary, ok := c.Elements[hash]
|
summary, ok := c.Elements[hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -133,12 +133,12 @@ func (c *SummaryContainer) Get(metricName string, labels prometheus.Labels) prom
|
||||||
Help: defaultHelp,
|
Help: defaultHelp,
|
||||||
ConstLabels: labels,
|
ConstLabels: labels,
|
||||||
})
|
})
|
||||||
c.Elements[hash] = summary
|
|
||||||
if err := prometheus.Register(summary); err != nil {
|
if err := prometheus.Register(summary); err != nil {
|
||||||
log.Fatalf(regErrF, metricName, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.Elements[hash] = summary
|
||||||
}
|
}
|
||||||
return summary
|
return summary, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event interface {
|
type Event interface {
|
||||||
|
@ -233,10 +233,6 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
|
|
||||||
switch ev := event.(type) {
|
switch ev := event.(type) {
|
||||||
case *CounterEvent:
|
case *CounterEvent:
|
||||||
counter := b.Counters.Get(
|
|
||||||
b.suffix(metricName, "counter"),
|
|
||||||
prometheusLabels,
|
|
||||||
)
|
|
||||||
// We don't accept negative values for counters. Incrementing the counter with a negative number
|
// We don't accept negative values for counters. Incrementing the counter with a negative number
|
||||||
// will cause the exporter to panic. Instead we will warn and continue to the next event.
|
// will cause the exporter to panic. Instead we will warn and continue to the next event.
|
||||||
if event.Value() < 0.0 {
|
if event.Value() < 0.0 {
|
||||||
|
@ -244,16 +240,26 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
counter, err := b.Counters.Get(
|
||||||
|
b.suffix(metricName, "counter"),
|
||||||
|
prometheusLabels,
|
||||||
|
)
|
||||||
|
if err == nil {
|
||||||
counter.Add(event.Value())
|
counter.Add(event.Value())
|
||||||
|
|
||||||
eventStats.WithLabelValues("counter").Inc()
|
eventStats.WithLabelValues("counter").Inc()
|
||||||
|
} else {
|
||||||
|
log.Errorf(regErrF, metricName, err)
|
||||||
|
conflictingEventStats.WithLabelValues("counter").Inc()
|
||||||
|
}
|
||||||
|
|
||||||
case *GaugeEvent:
|
case *GaugeEvent:
|
||||||
gauge := b.Gauges.Get(
|
gauge, err := b.Gauges.Get(
|
||||||
b.suffix(metricName, "gauge"),
|
b.suffix(metricName, "gauge"),
|
||||||
prometheusLabels,
|
prometheusLabels,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
if ev.relative {
|
if ev.relative {
|
||||||
gauge.Add(event.Value())
|
gauge.Add(event.Value())
|
||||||
} else {
|
} else {
|
||||||
|
@ -261,15 +267,24 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eventStats.WithLabelValues("gauge").Inc()
|
eventStats.WithLabelValues("gauge").Inc()
|
||||||
|
} else {
|
||||||
|
log.Errorf(regErrF, metricName, err)
|
||||||
|
conflictingEventStats.WithLabelValues("gauge").Inc()
|
||||||
|
}
|
||||||
|
|
||||||
case *TimerEvent:
|
case *TimerEvent:
|
||||||
summary := b.Summaries.Get(
|
summary, err := b.Summaries.Get(
|
||||||
b.suffix(metricName, "timer"),
|
b.suffix(metricName, "timer"),
|
||||||
prometheusLabels,
|
prometheusLabels,
|
||||||
)
|
)
|
||||||
|
if err == nil {
|
||||||
summary.Observe(event.Value())
|
summary.Observe(event.Value())
|
||||||
|
|
||||||
eventStats.WithLabelValues("timer").Inc()
|
eventStats.WithLabelValues("timer").Inc()
|
||||||
|
} else {
|
||||||
|
log.Errorf(regErrF, metricName, err)
|
||||||
|
conflictingEventStats.WithLabelValues("timer").Inc()
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Errorln("Unsupported event type")
|
log.Errorln("Unsupported event type")
|
||||||
|
|
|
@ -47,6 +47,13 @@ var (
|
||||||
Name: "statsd_exporter_loaded_mappings",
|
Name: "statsd_exporter_loaded_mappings",
|
||||||
Help: "The current number of configured metric mappings.",
|
Help: "The current number of configured metric mappings.",
|
||||||
})
|
})
|
||||||
|
conflictingEventStats = prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Name: "statsd_exporter_events_conflict_total",
|
||||||
|
Help: "The total number of StatsD events with conflicting names.",
|
||||||
|
},
|
||||||
|
[]string{"type"},
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -54,4 +61,5 @@ func init() {
|
||||||
prometheus.MustRegister(networkStats)
|
prometheus.MustRegister(networkStats)
|
||||||
prometheus.MustRegister(configLoads)
|
prometheus.MustRegister(configLoads)
|
||||||
prometheus.MustRegister(mappingsCount)
|
prometheus.MustRegister(mappingsCount)
|
||||||
|
prometheus.MustRegister(conflictingEventStats)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue