From a9eef7c124fd02b2fe71e6f827479bcf9a1de21e Mon Sep 17 00:00:00 2001 From: Federico Torres Date: Thu, 5 Sep 2024 09:41:47 -0300 Subject: [PATCH 1/2] Fix multiple metric name inside braces validation Signed-off-by: Federico Torres --- expfmt/text_parse.go | 18 +++++++++++----- expfmt/text_parse_test.go | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/expfmt/text_parse.go b/expfmt/text_parse.go index 25db4f21..6cc03d07 100644 --- a/expfmt/text_parse.go +++ b/expfmt/text_parse.go @@ -73,9 +73,9 @@ type TextParser struct { // These tell us if the currently processed line ends on '_count' or // '_sum' respectively and belong to a summary/histogram, representing the sample // count and sum of that summary/histogram. - currentIsSummaryCount, currentIsSummarySum bool - currentIsHistogramCount, currentIsHistogramSum bool - currentMetricIsInsideBraces bool + currentIsSummaryCount, currentIsSummarySum bool + currentIsHistogramCount, currentIsHistogramSum bool + currentMetricIsInsideBraces, currentMetricInsideBracesIsPresent bool } // TextToMetricFamilies reads 'in' as the simple and flat text-based exchange @@ -147,6 +147,7 @@ func (p *TextParser) reset(in io.Reader) { func (p *TextParser) startOfLine() stateFn { p.lineCount++ p.currentMetricIsInsideBraces = false + p.currentMetricInsideBracesIsPresent = false if p.skipBlankTab(); p.err != nil { // This is the only place that we expect to see io.EOF, // which is not an error but the signal that we are done. @@ -301,17 +302,24 @@ func (p *TextParser) startLabelName() stateFn { } if p.currentByte != '=' { if p.currentMetricIsInsideBraces { - if p.currentMF != nil && p.currentMF.GetName() != p.currentToken.String() { - p.parseError(fmt.Sprintf("multiple metric names %s %s", p.currentMF.GetName(), p.currentToken.String())) + if p.currentMetricInsideBracesIsPresent { + p.parseError(fmt.Sprintf("multiple metric names for metric %q", p.currentMF.GetName())) return nil } switch p.currentByte { case ',': p.setOrCreateCurrentMF() + if p.currentMF.Type == nil { + p.currentMF.Type = dto.MetricType_UNTYPED.Enum() + } p.currentMetric = &dto.Metric{} + p.currentMetricInsideBracesIsPresent = true return p.startLabelName case '}': p.setOrCreateCurrentMF() + if p.currentMF.Type == nil { + p.currentMF.Type = dto.MetricType_UNTYPED.Enum() + } p.currentMetric = &dto.Metric{} p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) p.currentLabelPairs = nil diff --git a/expfmt/text_parse_test.go b/expfmt/text_parse_test.go index 1ddba297..fac60ba6 100644 --- a/expfmt/text_parse_test.go +++ b/expfmt/text_parse_test.go @@ -594,6 +594,49 @@ request_duration_microseconds_count 2693 }, }, }, + // 11: Multiple minimal metrics with quoted metric names. + { + in: ` +{"name.1"} 1 +{"name.2"} 1 +{"name.3"} 1 +`, + out: []*dto.MetricFamily{ + { + Name: proto.String("name.1"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + { + Untyped: &dto.Untyped{ + Value: proto.Float64(1), + }, + }, + }, + }, + { + Name: proto.String("name.2"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + { + Untyped: &dto.Untyped{ + Value: proto.Float64(1), + }, + }, + }, + }, + { + Name: proto.String("name.3"), + Type: dto.MetricType_UNTYPED.Enum(), + Metric: []*dto.Metric{ + { + Untyped: &dto.Untyped{ + Value: proto.Float64(1), + }, + }, + }, + }, + }, + }, } for i, scenario := range scenarios { From acd0c007ef78f0864cf33cfdd8d0acb7b8a2b61a Mon Sep 17 00:00:00 2001 From: Federico Torres Date: Thu, 5 Sep 2024 10:59:21 -0300 Subject: [PATCH 2/2] Add comment for clarification Signed-off-by: Federico Torres --- expfmt/text_parse.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/expfmt/text_parse.go b/expfmt/text_parse.go index 6cc03d07..f085a923 100644 --- a/expfmt/text_parse.go +++ b/expfmt/text_parse.go @@ -73,8 +73,10 @@ type TextParser struct { // These tell us if the currently processed line ends on '_count' or // '_sum' respectively and belong to a summary/histogram, representing the sample // count and sum of that summary/histogram. - currentIsSummaryCount, currentIsSummarySum bool - currentIsHistogramCount, currentIsHistogramSum bool + currentIsSummaryCount, currentIsSummarySum bool + currentIsHistogramCount, currentIsHistogramSum bool + // These indicate if the metric name from the current line being parsed is inside + // braces and if that metric name was found respectively. currentMetricIsInsideBraces, currentMetricInsideBracesIsPresent bool }