From c6f41ce391b0f8f570dd8a46b253ab7b25a07b77 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Tue, 18 Jul 2017 12:35:41 +0200 Subject: [PATCH] Allow metric and label names to begin with underscores (#2961) While this is not recommended, it is allowed in our data model (https://prometheus.io/docs/concepts/data_model/). Fixes https://github.com/prometheus/prometheus/issues/2959 --- pkg/textparse/lex.l | 13 ++++++------- pkg/textparse/lex.l.go | 11 +++++------ pkg/textparse/parse_test.go | 12 +++++++++++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/pkg/textparse/lex.l b/pkg/textparse/lex.l index c79094dca..5fd8c6e37 100644 --- a/pkg/textparse/lex.l +++ b/pkg/textparse/lex.l @@ -39,7 +39,7 @@ const ( // the end of the file. func (l *lexer) Lex() int { l.state = lstateInit - + if l.i >= len(l.b) { return eof } @@ -51,7 +51,6 @@ func (l *lexer) Lex() int { %} D [0-9] -S [a-zA-Z] L [a-zA-Z_] M [a-zA-Z_:] @@ -69,7 +68,7 @@ M [a-zA-Z_:] #[^\r\n]*\n l.mstart = l.i [\r\n \t]+ l.mstart = l.i -{S}({M}|{D})* l.state = lstateName +{M}({M}|{D})* l.state = lstateName l.offsets = append(l.offsets, l.i) l.mend = l.i @@ -85,7 +84,7 @@ M [a-zA-Z_:] (,?[ \t]*) l.state = lstateLName l.offsets = append(l.offsets, l.i) -{S}({L}|{D})* l.offsets = append(l.offsets, l.i) +{L}({L}|{D})* l.offsets = append(l.offsets, l.i) [ \t]*= l.state = lstateLValue [ \t]+ @@ -110,7 +109,7 @@ M [a-zA-Z_:] } l.state = lstateTimestamp -[ \t]+ l.tstart = l.i +[ \t]+ l.tstart = l.i {D}+ ts, err := strconv.ParseInt(yoloString(l.b[l.tstart:l.i]), 10, 64) if err != nil { l.err = err @@ -119,8 +118,8 @@ M [a-zA-Z_:] l.ts = &ts [\r\n]+ l.nextMstart = l.i return 1 -\0 return 1 - +\0 return 1 + %% l.err = fmt.Errorf("no token found") return -1 diff --git a/pkg/textparse/lex.l.go b/pkg/textparse/lex.l.go index 00f204faa..1622a6421 100644 --- a/pkg/textparse/lex.l.go +++ b/pkg/textparse/lex.l.go @@ -83,12 +83,12 @@ yystart1: goto yyabort case c == '#': goto yystate4 + case c == ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': + goto yystate6 case c == '\t' || c == '\n' || c == '\r' || c == ' ': goto yystate3 case c == '\x00': goto yystate2 - case c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z': - goto yystate6 } yystate2: @@ -327,7 +327,7 @@ yystart26: goto yystate28 case c == '\t' || c == ' ': goto yystate27 - case c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z': + case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate29 } @@ -436,7 +436,7 @@ yyrule3: // [\r\n \t]+ l.mstart = l.i goto yystate0 } -yyrule4: // {S}({M}|{D})* +yyrule4: // {M}({M}|{D})* { l.state = lstateName l.offsets = append(l.offsets, l.i) @@ -469,7 +469,7 @@ yyrule9: // (,?[ \t]*) l.offsets = append(l.offsets, l.i) goto yystate0 } -yyrule10: // {S}({L}|{D})* +yyrule10: // {L}({L}|{D})* { l.offsets = append(l.offsets, l.i) goto yystate0 @@ -543,7 +543,6 @@ yyrule20: // [\r\n]+ yyrule21: // \0 { return 1 - } panic("unreachable") diff --git a/pkg/textparse/parse_test.go b/pkg/textparse/parse_test.go index b1ef9cca0..25e11ef1f 100644 --- a/pkg/textparse/parse_test.go +++ b/pkg/textparse/parse_test.go @@ -43,7 +43,9 @@ go_gc_duration_seconds_count 99 some:aggregate:rate5m{a_b="c"} 1 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge -go_goroutines 33 123123` +go_goroutines 33 123123 +_metric_starting_with_underscore 1 +testmetric{_label_starting_with_underscore="foo"} 1` input += "\nnull_byte_metric{a=\"abc\x00\"} 1" int64p := func(x int64) *int64 { return &x } @@ -103,6 +105,14 @@ go_goroutines 33 123123` v: 33, t: int64p(123123), lset: labels.FromStrings("__name__", "go_goroutines"), + }, { + m: "_metric_starting_with_underscore", + v: 1, + lset: labels.FromStrings("__name__", "_metric_starting_with_underscore"), + }, { + m: "testmetric{_label_starting_with_underscore=\"foo\"}", + v: 1, + lset: labels.FromStrings("__name__", "testmetric", "_label_starting_with_underscore", "foo"), }, { m: "null_byte_metric{a=\"abc\x00\"}", v: 1,