forked from mirrors/statsd_exporter
feat: handle double dashes in unmapped metrics (#389)
Signed-off-by: akartasov <agneum@gmail.com>
This commit is contained in:
parent
95d34445ed
commit
2ab2c442cf
2 changed files with 15 additions and 1 deletions
|
@ -39,6 +39,7 @@ func EscapeMetricName(metricName string) string {
|
||||||
// This is an character replacement method optimized for this limited
|
// This is an character replacement method optimized for this limited
|
||||||
// use case. It is much faster than using a regex.
|
// use case. It is much faster than using a regex.
|
||||||
offset := 0
|
offset := 0
|
||||||
|
var prevChar rune
|
||||||
for i, c := range metricName {
|
for i, c := range metricName {
|
||||||
// Seek forward, skipping valid characters until we find one that needs
|
// Seek forward, skipping valid characters until we find one that needs
|
||||||
// to be replaced, then add all the characters we've seen so far to the
|
// to be replaced, then add all the characters we've seen so far to the
|
||||||
|
@ -47,6 +48,13 @@ func EscapeMetricName(metricName string) string {
|
||||||
(c >= '0' && c <= '9') || (c == '_') {
|
(c >= '0' && c <= '9') || (c == '_') {
|
||||||
// Character is valid, so skip over it without doing anything.
|
// Character is valid, so skip over it without doing anything.
|
||||||
} else {
|
} else {
|
||||||
|
// Double-dashes are allowed if there is a corresponding mapping.
|
||||||
|
// For consistency, double-dashes should also be allowed in the default case.
|
||||||
|
if c == '-' && prevChar == '-' {
|
||||||
|
offset = i + utf8.RuneLen(c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !escaped {
|
if !escaped {
|
||||||
// Up until now we've been lazy and avoided actually allocating
|
// Up until now we've been lazy and avoided actually allocating
|
||||||
// memory. Unfortunately we've now determined this string needs
|
// memory. Unfortunately we've now determined this string needs
|
||||||
|
@ -58,6 +66,8 @@ func EscapeMetricName(metricName string) string {
|
||||||
offset = i + utf8.RuneLen(c)
|
offset = i + utf8.RuneLen(c)
|
||||||
sb.WriteByte('_')
|
sb.WriteByte('_')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevChar = c
|
||||||
}
|
}
|
||||||
|
|
||||||
if !escaped {
|
if !escaped {
|
||||||
|
|
|
@ -20,6 +20,8 @@ func TestEscapeMetricName(t *testing.T) {
|
||||||
"clean": "clean",
|
"clean": "clean",
|
||||||
"0starts_with_digit": "_0starts_with_digit",
|
"0starts_with_digit": "_0starts_with_digit",
|
||||||
"with_underscore": "with_underscore",
|
"with_underscore": "with_underscore",
|
||||||
|
"with--doubledash": "with_doubledash",
|
||||||
|
"with---multiple-dashes": "with_multiple_dashes",
|
||||||
"with.dot": "with_dot",
|
"with.dot": "with_dot",
|
||||||
"with😱emoji": "with_emoji",
|
"with😱emoji": "with_emoji",
|
||||||
"with.*.multiple": "with___multiple",
|
"with.*.multiple": "with___multiple",
|
||||||
|
@ -39,6 +41,8 @@ func BenchmarkEscapeMetricName(b *testing.B) {
|
||||||
"clean",
|
"clean",
|
||||||
"0starts_with_digit",
|
"0starts_with_digit",
|
||||||
"with_underscore",
|
"with_underscore",
|
||||||
|
"with--doubledash",
|
||||||
|
"with---multiple-dashes",
|
||||||
"with.dot",
|
"with.dot",
|
||||||
"with😱emoji",
|
"with😱emoji",
|
||||||
"with.*.multiple",
|
"with.*.multiple",
|
||||||
|
|
Loading…
Reference in a new issue