From 1d7ab78b552ef60e190672c7344560822a719bfa Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 2 Mar 2020 22:21:50 +0200 Subject: [PATCH] lib/protoparser/prometheus: allow trailing comma in tags list The trailing comma is generated by cloudwatch exporter. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/350 --- lib/protoparser/prometheus/parser.go | 12 ++++++------ lib/protoparser/prometheus/parser_test.go | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/protoparser/prometheus/parser.go b/lib/protoparser/prometheus/parser.go index f1f97b9ca..27cd4a637 100644 --- a/lib/protoparser/prometheus/parser.go +++ b/lib/protoparser/prometheus/parser.go @@ -193,12 +193,12 @@ func unmarshalRow(dst []Row, s string, tagsPool []Tag, noEscapes bool, errLogger var invalidLines = metrics.NewCounter(`vm_rows_invalid_total{type="prometheus"}`) func unmarshalTags(dst []Tag, s string, noEscapes bool) (string, []Tag, error) { - s = skipLeadingWhitespace(s) - if len(s) > 0 && s[0] == '}' { - // End of tags found. - return s[1:], dst, nil - } for { + s = skipLeadingWhitespace(s) + if len(s) > 0 && s[0] == '}' { + // End of tags found. + return s[1:], dst, nil + } n := strings.IndexByte(s, '=') if n < 0 { return s, dst, fmt.Errorf("missing value for tag %q", s) @@ -248,7 +248,7 @@ func unmarshalTags(dst []Tag, s string, noEscapes bool) (string, []Tag, error) { if len(s) == 0 || s[0] != ',' { return s, dst, fmt.Errorf("missing comma after tag %s=%q", key, value) } - s = skipLeadingWhitespace(s[1:]) + s = s[1:] } } diff --git a/lib/protoparser/prometheus/parser_test.go b/lib/protoparser/prometheus/parser_test.go index 3a5628c72..ce945bf39 100644 --- a/lib/protoparser/prometheus/parser_test.go +++ b/lib/protoparser/prometheus/parser_test.go @@ -111,15 +111,14 @@ func TestRowsUnmarshalFailure(t *testing.T) { f("a{") f("a { ") f("a {foo") - f("a {foo}") + f("a {foo} 3") f("a {foo =") f(`a {foo ="bar`) f(`a {foo ="b\ar`) f(`a {foo = "bar"`) f(`a {foo ="bar",`) f(`a {foo ="bar" , `) - f(`a {foo ="bar" , }`) - f(`a {foo ="bar" , baz }`) + f(`a {foo ="bar" , baz } 2`) // empty metric name f(`{foo="bar"}`) @@ -232,6 +231,20 @@ func TestRowsUnmarshalSuccess(t *testing.T) { }}, }) + // Trailing comma after tag + // See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/350 + f(`foo{bar="baz",} 1 2`, &Rows{ + Rows: []Row{{ + Metric: "foo", + Tags: []Tag{{ + Key: "bar", + Value: "baz", + }}, + Value: 1, + Timestamp: 2, + }}, + }) + // Multi lines f("# foo\n # bar ba zzz\nfoo 0.3 2\naaa 3\nbar.baz 0.34 43\n", &Rows{ Rows: []Row{