forked from mirrors/statsd_exporter
Ensure valid metric names and change statsd metric escaping.
This commit is contained in:
parent
eff54bdcf9
commit
728bdc52ae
3 changed files with 26 additions and 5 deletions
16
bridge.go
16
bridge.go
|
@ -10,12 +10,17 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
illegalCharsRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
|
||||||
|
)
|
||||||
|
|
||||||
type CounterContainer struct {
|
type CounterContainer struct {
|
||||||
Elements map[string]prometheus.Counter
|
Elements map[string]prometheus.Counter
|
||||||
}
|
}
|
||||||
|
@ -121,10 +126,13 @@ type Bridge struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func escapeMetricName(metricName string) string {
|
func escapeMetricName(metricName string) string {
|
||||||
// TODO: evaluate what kind of escaping we really want.
|
// If a metric starts with a digit, prepend an underscore.
|
||||||
metricName = strings.Replace(metricName, "_", "__", -1)
|
if metricName[0] >= '0' && metricName[0] <= '9' {
|
||||||
metricName = strings.Replace(metricName, "-", "__", -1)
|
metricName = "_" + metricName
|
||||||
metricName = strings.Replace(metricName, ".", "_", -1)
|
}
|
||||||
|
|
||||||
|
// Replace all illegal metric chars with underscores.
|
||||||
|
metricName = illegalCharsRE.ReplaceAllString(metricName, "_")
|
||||||
return metricName
|
return metricName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ var (
|
||||||
identifierRE = `[a-zA-Z_][a-zA-Z0-9_]+`
|
identifierRE = `[a-zA-Z_][a-zA-Z0-9_]+`
|
||||||
metricLineRE = regexp.MustCompile(`^(\*\.|` + identifierRE + `\.)+(\*|` + identifierRE + `)$`)
|
metricLineRE = regexp.MustCompile(`^(\*\.|` + identifierRE + `\.)+(\*|` + identifierRE + `)$`)
|
||||||
labelLineRE = regexp.MustCompile(`^(` + identifierRE + `)\s*=\s*"(.*)"$`)
|
labelLineRE = regexp.MustCompile(`^(` + identifierRE + `)\s*=\s*"(.*)"$`)
|
||||||
|
metricNameRE = regexp.MustCompile(`^` + identifierRE + `$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type metricMapping struct {
|
type metricMapping struct {
|
||||||
|
@ -85,7 +86,11 @@ func (m *metricMapper) initFromString(fileContents string) error {
|
||||||
if len(matches) != 3 {
|
if len(matches) != 3 {
|
||||||
return fmt.Errorf("Line %d: expected label mapping line, got: %s", i, line)
|
return fmt.Errorf("Line %d: expected label mapping line, got: %s", i, line)
|
||||||
}
|
}
|
||||||
currentMapping.labels[matches[1]] = matches[2]
|
label, value := matches[1], matches[2]
|
||||||
|
if label == "name" && !metricNameRE.MatchString(value) {
|
||||||
|
return fmt.Errorf("Line %d: metric name '%s' doesn't match regex '%s'", i, value, metricNameRE)
|
||||||
|
}
|
||||||
|
currentMapping.labels[label] = value
|
||||||
default:
|
default:
|
||||||
panic("illegal state")
|
panic("illegal state")
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,14 @@ func TestMetricMapper(t *testing.T) {
|
||||||
`,
|
`,
|
||||||
configBad: true,
|
configBad: true,
|
||||||
},
|
},
|
||||||
|
// Config with bad metric name.
|
||||||
|
{
|
||||||
|
config: `
|
||||||
|
test.*.*
|
||||||
|
name="0foo"
|
||||||
|
`,
|
||||||
|
configBad: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper := metricMapper{}
|
mapper := metricMapper{}
|
||||||
|
|
Loading…
Reference in a new issue