forked from mirrors/statsd_exporter
Merge pull request #37 from prometheus/fish/remove-auto-suffixes
Make metric suffixes optional, expose unmapped events
This commit is contained in:
commit
8e43fc2654
4 changed files with 46 additions and 22 deletions
37
README.md
37
README.md
|
@ -67,28 +67,33 @@ Metrics that don't match any mapping in the configuration file are translated
|
||||||
into Prometheus metrics without any labels and with certain characters escaped
|
into Prometheus metrics without any labels and with certain characters escaped
|
||||||
(`_` -> `__`; `-` -> `__`; `.` -> `_`).
|
(`_` -> `__`; `-` -> `__`; `.` -> `_`).
|
||||||
|
|
||||||
In general, the different metric types are translated as follows, with certain
|
In general, the different metric types are translated as follows:
|
||||||
suffixes appended to the Prometheus metric names:
|
|
||||||
|
|
||||||
StatsD gauge -> Prometheus gauge (suffix `_gauge`)
|
StatsD gauge -> Prometheus gauge
|
||||||
|
|
||||||
StatsD counter -> Prometheus counter (suffix `_counter`)
|
StatsD counter -> Prometheus counter
|
||||||
|
|
||||||
StatsD timer -> Prometheus summary (suffix `_timer`) <-- indicates timer quantiles
|
StatsD timer -> Prometheus summary <-- indicates timer quantiles
|
||||||
-> Prometheus counter (suffix `_timer_total`) <-- indicates total time spent
|
-> Prometheus counter (suffix `_total`) <-- indicates total time spent
|
||||||
-> Prometheus counter (suffix `_timer_count`) <-- indicates total number of timer events
|
-> Prometheus counter (suffix `_count`) <-- indicates total number of timer events
|
||||||
|
|
||||||
An example mapping configuration:
|
If `-statsd.add-suffix` is set, the exporter appends the metric type (`_gauge`,
|
||||||
|
`_counter`, `_timer`) to the resulting metrics. This is enabled by default for
|
||||||
|
backward compatibility but discouraged to use. Instead, it is better to
|
||||||
|
explicitly define the full metric name in your mapping and run the exporter
|
||||||
|
with `-statsd.add-suffix=false`.
|
||||||
|
|
||||||
|
An example mapping configuration with `-statsd.add-suffix=false`:
|
||||||
|
|
||||||
test.dispatcher.*.*.*
|
test.dispatcher.*.*.*
|
||||||
name="dispatcher_events"
|
name="dispatcher_events_total"
|
||||||
processor="$1"
|
processor="$1"
|
||||||
action="$2"
|
action="$2"
|
||||||
outcome="$3"
|
outcome="$3"
|
||||||
job="test_dispatcher"
|
job="test_dispatcher"
|
||||||
|
|
||||||
*.signup.*.*
|
*.signup.*.*
|
||||||
name="signup_events"
|
name="signup_events_total"
|
||||||
provider="$2"
|
provider="$2"
|
||||||
outcome="$3"
|
outcome="$3"
|
||||||
job="${1}_server"
|
job="${1}_server"
|
||||||
|
@ -96,14 +101,14 @@ An example mapping configuration:
|
||||||
This would transform these example StatsD metrics into Prometheus metrics as
|
This would transform these example StatsD metrics into Prometheus metrics as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
test.dispatcher.FooProcessor.send.success (counter)
|
test.dispatcher.FooProcessor.send.success
|
||||||
=> dispatcher_events_counter{processor="FooProcessor", action="send", outcome="success", job="test_dispatcher"}
|
=> dispatcher_events_total{processor="FooProcessor", action="send", outcome="success", job="test_dispatcher"}
|
||||||
|
|
||||||
foo_product.signup.facebook.failure (counter)
|
foo_product.signup.facebook.failure
|
||||||
=> signup_events_counter{provider="facebook", outcome="failure", job="foo_product_server"}
|
=> signup_events_total{provider="facebook", outcome="failure", job="foo_product_server"}
|
||||||
|
|
||||||
test.web-server.foo.bar (gauge)
|
test.web-server.foo.bar
|
||||||
=> test_web__server_foo_bar_gauge{}
|
=> test_web__server_foo_bar{}
|
||||||
|
|
||||||
## Using Docker
|
## Using Docker
|
||||||
|
|
||||||
|
|
19
exporter.go
19
exporter.go
|
@ -183,6 +183,7 @@ type Exporter struct {
|
||||||
Gauges *GaugeContainer
|
Gauges *GaugeContainer
|
||||||
Summaries *SummaryContainer
|
Summaries *SummaryContainer
|
||||||
mapper *metricMapper
|
mapper *metricMapper
|
||||||
|
addSuffix bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func escapeMetricName(metricName string) string {
|
func escapeMetricName(metricName string) string {
|
||||||
|
@ -196,6 +197,14 @@ func escapeMetricName(metricName string) string {
|
||||||
return metricName
|
return metricName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Exporter) suffix(metricName, suffix string) string {
|
||||||
|
str := metricName
|
||||||
|
if b.addSuffix {
|
||||||
|
str += "_" + suffix
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Exporter) Listen(e <-chan Events) {
|
func (b *Exporter) Listen(e <-chan Events) {
|
||||||
for {
|
for {
|
||||||
events, ok := <-e
|
events, ok := <-e
|
||||||
|
@ -216,13 +225,14 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
eventsUnmapped.Inc()
|
||||||
metricName = escapeMetricName(event.MetricName())
|
metricName = escapeMetricName(event.MetricName())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch event.(type) {
|
switch event.(type) {
|
||||||
case *CounterEvent:
|
case *CounterEvent:
|
||||||
counter := b.Counters.Get(
|
counter := b.Counters.Get(
|
||||||
metricName+"_counter",
|
b.suffix(metricName, "counter"),
|
||||||
prometheusLabels,
|
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
|
||||||
|
@ -238,7 +248,7 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
|
|
||||||
case *GaugeEvent:
|
case *GaugeEvent:
|
||||||
gauge := b.Gauges.Get(
|
gauge := b.Gauges.Get(
|
||||||
metricName+"_gauge",
|
b.suffix(metricName, "gauge"),
|
||||||
prometheusLabels,
|
prometheusLabels,
|
||||||
)
|
)
|
||||||
gauge.Set(event.Value())
|
gauge.Set(event.Value())
|
||||||
|
@ -247,7 +257,7 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
|
|
||||||
case *TimerEvent:
|
case *TimerEvent:
|
||||||
summary := b.Summaries.Get(
|
summary := b.Summaries.Get(
|
||||||
metricName+"_timer",
|
b.suffix(metricName, "timer"),
|
||||||
prometheusLabels,
|
prometheusLabels,
|
||||||
)
|
)
|
||||||
summary.Observe(event.Value())
|
summary.Observe(event.Value())
|
||||||
|
@ -262,8 +272,9 @@ func (b *Exporter) Listen(e <-chan Events) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExporter(mapper *metricMapper) *Exporter {
|
func NewExporter(mapper *metricMapper, addSuffix bool) *Exporter {
|
||||||
return &Exporter{
|
return &Exporter{
|
||||||
|
addSuffix: addSuffix,
|
||||||
Counters: NewCounterContainer(),
|
Counters: NewCounterContainer(),
|
||||||
Gauges: NewGaugeContainer(),
|
Gauges: NewGaugeContainer(),
|
||||||
Summaries: NewSummaryContainer(),
|
Summaries: NewSummaryContainer(),
|
||||||
|
|
6
main.go
6
main.go
|
@ -30,6 +30,7 @@ var (
|
||||||
statsdListenAddress = flag.String("statsd.listen-address", ":9125", "The UDP address on which to receive statsd metric lines.")
|
statsdListenAddress = flag.String("statsd.listen-address", ":9125", "The UDP address on which to receive statsd metric lines.")
|
||||||
mappingConfig = flag.String("statsd.mapping-config", "", "Metric mapping configuration file name.")
|
mappingConfig = flag.String("statsd.mapping-config", "", "Metric mapping configuration file name.")
|
||||||
readBuffer = flag.Int("statsd.read-buffer", 0, "Size (in bytes) of the operating system's transmit read buffer associated with the UDP connection. Please make sure the kernel parameters net.core.rmem_max is set to a value greater than the value specified.")
|
readBuffer = flag.Int("statsd.read-buffer", 0, "Size (in bytes) of the operating system's transmit read buffer associated with the UDP connection. Please make sure the kernel parameters net.core.rmem_max is set to a value greater than the value specified.")
|
||||||
|
addSuffix = flag.Bool("statsd.add-suffix", true, "Add the metric type (counter/gauge/timer) as suffix to the generated Prometheus metric (NOT recommended, but set by default for backward compatibility).")
|
||||||
)
|
)
|
||||||
|
|
||||||
func serveHTTP() {
|
func serveHTTP() {
|
||||||
|
@ -108,6 +109,9 @@ func watchConfig(fileName string, mapper *metricMapper) {
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
if *addSuffix {
|
||||||
|
log.Println("Warning: Using -statsd.add-suffix is discouraged. We recommend explicitly naming metrics appropriately in the mapping configuration.")
|
||||||
|
}
|
||||||
log.Println("Starting StatsD -> Prometheus Exporter...")
|
log.Println("Starting StatsD -> Prometheus Exporter...")
|
||||||
log.Println("Accepting StatsD Traffic on", *statsdListenAddress)
|
log.Println("Accepting StatsD Traffic on", *statsdListenAddress)
|
||||||
log.Println("Accepting Prometheus Requests on", *listenAddress)
|
log.Println("Accepting Prometheus Requests on", *listenAddress)
|
||||||
|
@ -141,6 +145,6 @@ func main() {
|
||||||
}
|
}
|
||||||
go watchConfig(*mappingConfig, mapper)
|
go watchConfig(*mappingConfig, mapper)
|
||||||
}
|
}
|
||||||
exporter := NewExporter(mapper)
|
exporter := NewExporter(mapper, *addSuffix)
|
||||||
exporter.Listen(events)
|
exporter.Listen(events)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ var (
|
||||||
},
|
},
|
||||||
[]string{"type"},
|
[]string{"type"},
|
||||||
)
|
)
|
||||||
|
eventsUnmapped = prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "statsd_exporter_events_unmapped_total",
|
||||||
|
Help: "The total number of StatsD events no mapping was found for.",
|
||||||
|
})
|
||||||
networkStats = prometheus.NewCounterVec(
|
networkStats = prometheus.NewCounterVec(
|
||||||
prometheus.CounterOpts{
|
prometheus.CounterOpts{
|
||||||
Name: "statsd_exporter_packets_total",
|
Name: "statsd_exporter_packets_total",
|
||||||
|
@ -41,7 +45,7 @@ var (
|
||||||
)
|
)
|
||||||
mappingsCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
mappingsCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
Name: "statsd_exporter_loaded_mappings_count",
|
Name: "statsd_exporter_loaded_mappings_count",
|
||||||
Help: "The number of configured metric mappings.",
|
Help: "The current number of configured metric mappings.",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue