Merge pull request #15260 from tcolgate/quoteexemplarkeys

bugfix: allow quoted exemplar keys in openmetrics text format
pull/14887/merge
Bartlomiej Plotka 2024-11-26 02:52:17 -07:00 committed by GitHub
commit 11d9da1e48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 112 additions and 60 deletions

View File

@ -69,6 +69,7 @@ S [ ]
<sTimestamp>{S}#{S}\{ l.state = sExemplar; return tComment <sTimestamp>{S}#{S}\{ l.state = sExemplar; return tComment
<sExemplar>{L}({L}|{D})* return tLName <sExemplar>{L}({L}|{D})* return tLName
<sExemplar>\"(\\.|[^\\"\n])*\" l.state = sExemplar; return tQString
<sExemplar>\} l.state = sEValue; return tBraceClose <sExemplar>\} l.state = sEValue; return tBraceClose
<sExemplar>= l.state = sEValue; return tEqual <sExemplar>= l.state = sEValue; return tEqual
<sEValue>\"(\\.|[^\\"\n])*\" l.state = sExemplar; return tLValue <sEValue>\"(\\.|[^\\"\n])*\" l.state = sExemplar; return tLValue

View File

@ -53,9 +53,9 @@ yystate0:
case 8: // start condition: sExemplar case 8: // start condition: sExemplar
goto yystart57 goto yystart57
case 9: // start condition: sEValue case 9: // start condition: sEValue
goto yystart62 goto yystart65
case 10: // start condition: sETimestamp case 10: // start condition: sETimestamp
goto yystart68 goto yystart71
} }
yystate1: yystate1:
@ -538,125 +538,153 @@ yystart57:
switch { switch {
default: default:
goto yyabort goto yyabort
case c == ',': case c == '"':
goto yystate58 goto yystate58
case c == '=': case c == ',':
goto yystate59
case c == '}':
goto yystate61 goto yystate61
case c == '=':
goto yystate62
case c == '}':
goto yystate64
case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
goto yystate60 goto yystate63
} }
yystate58: yystate58:
c = l.next() c = l.next()
goto yyrule26 switch {
default:
goto yyabort
case c == '"':
goto yystate59
case c == '\\':
goto yystate60
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
goto yystate58
}
yystate59: yystate59:
c = l.next() c = l.next()
goto yyrule24 goto yyrule23
yystate60: yystate60:
c = l.next() c = l.next()
switch { switch {
default: default:
goto yyrule22 goto yyabort
case c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
goto yystate60 goto yystate58
} }
yystate61: yystate61:
c = l.next() c = l.next()
goto yyrule23 goto yyrule27
yystate62: yystate62:
c = l.next() c = l.next()
yystart62: goto yyrule25
switch {
default:
goto yyabort
case c == ' ':
goto yystate63
case c == '"':
goto yystate65
}
yystate63: yystate63:
c = l.next() c = l.next()
switch { switch {
default: default:
goto yyabort goto yyrule22
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ': case c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
goto yystate64 goto yystate63
} }
yystate64: yystate64:
c = l.next() c = l.next()
switch { goto yyrule24
default:
goto yyrule27
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
goto yystate64
}
yystate65: yystate65:
c = l.next() c = l.next()
yystart65:
switch { switch {
default: default:
goto yyabort goto yyabort
case c == '"': case c == ' ':
goto yystate66 goto yystate66
case c == '\\': case c == '"':
goto yystate67 goto yystate68
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
goto yystate65
} }
yystate66: yystate66:
c = l.next() c = l.next()
goto yyrule25 switch {
default:
goto yyabort
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
goto yystate67
}
yystate67: yystate67:
c = l.next() c = l.next()
switch { switch {
default: default:
goto yyabort goto yyrule28
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ': case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
goto yystate65 goto yystate67
} }
yystate68: yystate68:
c = l.next() c = l.next()
yystart68:
switch { switch {
default: default:
goto yyabort goto yyabort
case c == ' ': case c == '"':
goto yystate70
case c == '\n':
goto yystate69 goto yystate69
case c == '\\':
goto yystate70
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
goto yystate68
} }
yystate69: yystate69:
c = l.next() c = l.next()
goto yyrule29 goto yyrule26
yystate70: yystate70:
c = l.next() c = l.next()
switch { switch {
default: default:
goto yyabort goto yyabort
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ': case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
goto yystate71 goto yystate68
} }
yystate71: yystate71:
c = l.next() c = l.next()
yystart71:
switch { switch {
default: default:
goto yyrule28 goto yyabort
case c == ' ':
goto yystate73
case c == '\n':
goto yystate72
}
yystate72:
c = l.next()
goto yyrule30
yystate73:
c = l.next()
switch {
default:
goto yyabort
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ': case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
goto yystate71 goto yystate74
}
yystate74:
c = l.next()
switch {
default:
goto yyrule29
case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
goto yystate74
} }
yyrule1: // #{S} yyrule1: // #{S}
@ -782,39 +810,45 @@ yyrule22: // {L}({L}|{D})*
{ {
return tLName return tLName
} }
yyrule23: // \} yyrule23: // \"(\\.|[^\\"\n])*\"
{
l.state = sExemplar
return tQString
goto yystate0
}
yyrule24: // \}
{ {
l.state = sEValue l.state = sEValue
return tBraceClose return tBraceClose
goto yystate0 goto yystate0
} }
yyrule24: // = yyrule25: // =
{ {
l.state = sEValue l.state = sEValue
return tEqual return tEqual
goto yystate0 goto yystate0
} }
yyrule25: // \"(\\.|[^\\"\n])*\" yyrule26: // \"(\\.|[^\\"\n])*\"
{ {
l.state = sExemplar l.state = sExemplar
return tLValue return tLValue
goto yystate0 goto yystate0
} }
yyrule26: // , yyrule27: // ,
{ {
return tComma return tComma
} }
yyrule27: // {S}[^ \n]+ yyrule28: // {S}[^ \n]+
{ {
l.state = sETimestamp l.state = sETimestamp
return tValue return tValue
goto yystate0 goto yystate0
} }
yyrule28: // {S}[^ \n]+ yyrule29: // {S}[^ \n]+
{ {
return tTimestamp return tTimestamp
} }
yyrule29: // \n yyrule30: // \n
if true { // avoid go vet determining the below panic will not be reached if true { // avoid go vet determining the below panic will not be reached
l.state = sInit l.state = sInit
return tLinebreak return tLinebreak
@ -859,10 +893,10 @@ yyabort: // no lexem recognized
goto yystate57 goto yystate57
} }
if false { if false {
goto yystate62 goto yystate65
} }
if false { if false {
goto yystate68 goto yystate71
} }
} }

View File

@ -486,9 +486,12 @@ func TestUTF8OpenMetricsParse(t *testing.T) {
{"http.status",q="0.9",a="b"} 8.3835e-05 {"http.status",q="0.9",a="b"} 8.3835e-05
{q="0.9","http.status",a="b"} 8.3835e-05 {q="0.9","http.status",a="b"} 8.3835e-05
{"go.gc_duration_seconds_sum"} 0.004304266 {"go.gc_duration_seconds_sum"} 0.004304266
{"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"} 10.0` {"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"} 10.0
quotedexemplar_count 1 # {"id.thing"="histogram-count-test"} 4
quotedexemplar2_count 1 # {"id.thing"="histogram-count-test",other="hello"} 4
`
input += "\n# EOF\n" input += "# EOF\n"
exp := []parsedEntry{ exp := []parsedEntry{
{ {
@ -535,6 +538,20 @@ func TestUTF8OpenMetricsParse(t *testing.T) {
v: 10.0, v: 10.0,
lset: labels.FromStrings("__name__", `Heizölrückstoßabdämpfung 10 metric with "interesting" {character lset: labels.FromStrings("__name__", `Heizölrückstoßabdämpfung 10 metric with "interesting" {character
choices}`, "strange©™\n'quoted' \"name\"", "6"), choices}`, "strange©™\n'quoted' \"name\"", "6"),
}, {
m: `quotedexemplar_count`,
v: 1,
lset: labels.FromStrings("__name__", "quotedexemplar_count"),
es: []exemplar.Exemplar{
{Labels: labels.FromStrings("id.thing", "histogram-count-test"), Value: 4},
},
}, {
m: `quotedexemplar2_count`,
v: 1,
lset: labels.FromStrings("__name__", "quotedexemplar2_count"),
es: []exemplar.Exemplar{
{Labels: labels.FromStrings("id.thing", "histogram-count-test", "other", "hello"), Value: 4},
},
}, },
} }