allow for dynamic metric name

This commit is contained in:
Erick Pintor 2018-01-16 11:16:15 -02:00
parent d96145e47f
commit 27ee4050c4
4 changed files with 52 additions and 7 deletions

View file

@ -123,7 +123,17 @@ follows:
test.web-server.foo.bar test.web-server.foo.bar
=> test_web_server_foo_bar{} => test_web_server_foo_bar{}
Each mapping in the configuration file must define a `name` for the metric. Each mapping in the configuration file must define a `name` for the metric. The
metric's name can contain `$n`-style references to be replaced by the n-th
wildcard match in the matching line. That allows for dynamic rewrites, such as:
```yaml
mappings:
- match: test.*.*.counter
name: "${2}_counter"
labels:
provider: "$1"
```
If the default metric help text is insufficient for your needs you may use the YAML If the default metric help text is insufficient for your needs you may use the YAML
configuration to specify a custom help text for each mapping: configuration to specify a custom help text for each mapping:

View file

@ -263,7 +263,7 @@ func (b *Exporter) Listen(e <-chan Events) {
help = mapping.HelpText help = mapping.HelpText
} }
if present { if present {
metricName = mapping.Name metricName = escapeMetricName(mapping.Name)
for label, value := range labels { for label, value := range labels {
prometheusLabels[label] = value prometheusLabels[label] = value
} }

View file

@ -25,12 +25,12 @@ import (
) )
var ( var (
identifierRE = `[a-zA-Z_][a-zA-Z0-9_]+` statsdMetricRE = `[a-zA-Z_](-?[a-zA-Z0-9_])+`
statsdMetricRE = `[a-zA-Z_](-?[a-zA-Z0-9_])+` templateReplaceRE = `(\$\{?\d+\}?)`
metricLineRE = regexp.MustCompile(`^(\*\.|` + statsdMetricRE + `\.)+(\*|` + statsdMetricRE + `)$`) metricLineRE = regexp.MustCompile(`^(\*\.|` + statsdMetricRE + `\.)+(\*|` + statsdMetricRE + `)$`)
labelLineRE = regexp.MustCompile(`^(` + identifierRE + `)\s*=\s*"(.*)"$`) metricNameRE = regexp.MustCompile(`^([a-zA-Z_]|` + templateReplaceRE + `)([a-zA-Z0-9_]|` + templateReplaceRE + `)*$`)
metricNameRE = regexp.MustCompile(`^` + identifierRE + `$`) labelNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]+$`)
) )
type mapperConfigDefaults struct { type mapperConfigDefaults struct {
@ -77,7 +77,7 @@ func (m *metricMapper) initFromYAMLString(fileContents string) error {
// check that label is correct // check that label is correct
for k := range currentMapping.Labels { for k := range currentMapping.Labels {
if !metricNameRE.MatchString(k) { if !labelNameRE.MatchString(k) {
return fmt.Errorf("invalid label key: %s", k) return fmt.Errorf("invalid label key: %s", k)
} }
} }
@ -150,11 +150,19 @@ func (m *metricMapper) getMapping(statsdMetric string) (*metricMapping, promethe
continue continue
} }
mapping.Name = string(mapping.regex.ExpandString(
[]byte{},
mapping.Name,
statsdMetric,
matches,
))
labels := prometheus.Labels{} labels := prometheus.Labels{}
for label, valueExpr := range mapping.Labels { for label, valueExpr := range mapping.Labels {
value := mapping.regex.ExpandString([]byte{}, valueExpr, statsdMetric, matches) value := mapping.regex.ExpandString([]byte{}, valueExpr, statsdMetric, matches)
labels[label] = string(value) labels[label] = string(value)
} }
return &mapping, labels, true return &mapping, labels, true
} }

View file

@ -184,6 +184,33 @@ mappings:
`, `,
configBad: true, configBad: true,
}, },
// Config with dynamic metric name.
{
config: `---
mappings:
- match: test1.*.*
name: "$1"
labels: {}
- match: test2.*.*
name: "${1}_$2"
labels: {}
- match: test3\.(\w+)\.(\w+)
match_type: regex
name: "${2}_$1"
labels: {}
`,
mappings: mappings{
"test1.total_requests.count": {
name: "total_requests",
},
"test2.total_requests.count": {
name: "total_requests_count",
},
"test3.total_requests.count": {
name: "count_total_requests",
},
},
},
// Config with bad metric name. // Config with bad metric name.
{ {
config: `--- config: `---