Merge pull request #402 from agneum/389-allow-multiple-dashes

feat: handle multiple dashes in unmapped metrics (#389)
This commit is contained in:
Matthias Rampke 2021-10-26 13:13:52 +02:00 committed by GitHub
commit 6c0283942c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 0 deletions

View file

@ -39,6 +39,9 @@ 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 +50,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 +68,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",