From 0c2c1d96f93e4b3fbcc8c9ce6d61133dc1ec022f Mon Sep 17 00:00:00 2001 From: Matthias Rampke Date: Sun, 15 Sep 2024 09:55:11 +0000 Subject: [PATCH 1/3] Fix panic when parsing invalid lines The line ``` |h|#consumer:Kafka::SharedConfigurationConsumer,topic:shared_configuration_update,partition:1,consumer_group:tc_rc_us ``` caused a panic because the line parsing _first_ splits by `:` and then failed to find a `|` to split on. Check that we get at least two "line parts" (i.e. splits around `|`) when we expect them, and if not, gracefully reject the line instead of crashing. Fixes #572. Signed-off-by: Matthias Rampke --- pkg/line/line.go | 11 ++++++++--- pkg/line/line_test.go | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/line/line.go b/pkg/line/line.go index 949a5ea..4abebca 100644 --- a/pkg/line/line.go +++ b/pkg/line/line.go @@ -211,7 +211,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s elements := strings.SplitN(line, ":", 2) if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) { sampleErrors.WithLabelValues("malformed_line").Inc() - level.Debug(logger).Log("msg", "Bad line from StatsD", "line", line) + level.Debug(logger).Log("msg", "Bad line", "line", line) return events } @@ -223,12 +223,17 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s // don't allow mixed tagging styles sampleErrors.WithLabelValues("mixed_tagging_styles").Inc() - level.Debug(logger).Log("msg", "Bad line (multiple tagging styles) from StatsD", "line", line) + level.Debug(logger).Log("msg", "Bad line (multiple tagging styles)", "line", line) return events } var samples []string lineParts := strings.SplitN(elements[1], "|", 3) + if len(lineParts) < 2 { + sampleErrors.WithLabelValues("not_enough_parts_after_colon").Inc() + level.Debug(logger).Log("msg", "Bad line: not enough '|'-delimited parts after first ':'", "line", line) + return events + } if strings.Contains(lineParts[0], ":") { // handle DogStatsD extended aggregation isValidAggType := false @@ -251,7 +256,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s samples = aggLines } else { sampleErrors.WithLabelValues("invalid_extended_aggregate_type").Inc() - level.Debug(logger).Log("msg", "Bad line (invalid extended aggregate type) from StatsD", "line", line) + level.Debug(logger).Log("msg", "Bad line (invalid extended aggregate type)", "line", line) return events } } else if usingDogStatsDTags { diff --git a/pkg/line/line_test.go b/pkg/line/line_test.go index 970320c..305d790 100644 --- a/pkg/line/line_test.go +++ b/pkg/line/line_test.go @@ -823,6 +823,12 @@ func TestLineToEvents(t *testing.T) { }, }, }, + "invalid event split over lines part 1": { + in: "karafka.consumer.consume.cpu_idle_second: 0.111090 -0.055903 -0.195390 ( 2.419002)", + }, + "invalid event split over lines part 2": { + in: "|h|#consumer:Kafka::SharedConfigurationConsumer,topic:shared_configuration_update,partition:1,consumer_group:tc_rc_us", + }, } parser := NewParser() From 1a5428f4efcb46d8078c4ab6fb2e1805b2af1e33 Mon Sep 17 00:00:00 2001 From: Matthias Rampke Date: Sun, 15 Sep 2024 11:50:55 +0000 Subject: [PATCH 2/3] Tidy up log messages in line parsing Use go-error-style colons to add more details. Un-capitalize. Signed-off-by: Matthias Rampke --- pkg/line/line.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/line/line.go b/pkg/line/line.go index 4abebca..97d669f 100644 --- a/pkg/line/line.go +++ b/pkg/line/line.go @@ -211,7 +211,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s elements := strings.SplitN(line, ":", 2) if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) { sampleErrors.WithLabelValues("malformed_line").Inc() - level.Debug(logger).Log("msg", "Bad line", "line", line) + level.Debug(logger).Log("msg", "bad line", "line", line) return events } @@ -223,7 +223,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s // don't allow mixed tagging styles sampleErrors.WithLabelValues("mixed_tagging_styles").Inc() - level.Debug(logger).Log("msg", "Bad line (multiple tagging styles)", "line", line) + level.Debug(logger).Log("msg", "bad line: multiple tagging styles", "line", line) return events } @@ -231,7 +231,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s lineParts := strings.SplitN(elements[1], "|", 3) if len(lineParts) < 2 { sampleErrors.WithLabelValues("not_enough_parts_after_colon").Inc() - level.Debug(logger).Log("msg", "Bad line: not enough '|'-delimited parts after first ':'", "line", line) + level.Debug(logger).Log("msg", "bad line: not enough '|'-delimited parts after first ':'", "line", line) return events } if strings.Contains(lineParts[0], ":") { @@ -256,7 +256,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s samples = aggLines } else { sampleErrors.WithLabelValues("invalid_extended_aggregate_type").Inc() - level.Debug(logger).Log("msg", "Bad line (invalid extended aggregate type)", "line", line) + level.Debug(logger).Log("msg", "bad line: invalid extended aggregate type", "line", line) return events } } else if usingDogStatsDTags { @@ -272,7 +272,7 @@ samples: components := strings.Split(sample, "|") if len(components) < 2 || len(components) > 4 { sampleErrors.WithLabelValues("malformed_component").Inc() - level.Debug(logger).Log("msg", "Bad component", "line", line) + level.Debug(logger).Log("msg", "bad component", "line", line) continue } valueStr, statType := components[0], components[1] @@ -284,7 +284,7 @@ samples: value, err := strconv.ParseFloat(valueStr, 64) if err != nil { - level.Debug(logger).Log("msg", "Bad value", "value", valueStr, "line", line) + level.Debug(logger).Log("msg", "bad value", "value", valueStr, "line", line) sampleErrors.WithLabelValues("malformed_value").Inc() continue } From a7b501d3f24bd6b24177b5e2a0934c3c31b3f44e Mon Sep 17 00:00:00 2001 From: Matthias Rampke Date: Mon, 16 Sep 2024 09:35:10 +0000 Subject: [PATCH 3/3] Test release for PR #579 Signed-off-by: Matthias Rampke --- CHANGELOG.md | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28bb9ff..4c3690c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.27.2-pr579 / 2024-09-16 + +* [BUGFIX] Fix panic on certain invalid lines ([#579](https://github.com/prometheus/statsd_exporter/pull/579)) + ## 0.27.1 / 2024-08-18 * [FEATURE] Support [dogstatsd extended aggregation](https://github.com/DataDog/datadog-go/blob/master/README.md#extended-aggregation) ([#558](https://github.com/prometheus/statsd_exporter/pull/558)) diff --git a/VERSION b/VERSION index 83b4730..ff3932d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.1 +0.27.2-pr579