feat: handle double dashes in unmapped metrics (#389)

Signed-off-by: akartasov <agneum@gmail.com>
This commit is contained in:
akartasov 2021-10-23 23:45:19 +07:00
parent 95d34445ed
commit 2ab2c442cf
No known key found for this signature in database
GPG key ID: 9EDC00917A50AED6
2 changed files with 15 additions and 1 deletions

View file

@ -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 {

View file

@ -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",