Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions pkg/line/line.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,20 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
return events
}

// A DogStatsD line may carry a v1.2 container ID field (|c:<id>) without any
// |# tags. The container ID field is always the final pipe-delimited field and
// its value may itself contain ':' (for example |c:sha256:...), so such a line
// must skip the legacy multi-metric ':' split below, which would otherwise
// shred the field and drop the sample as malformed_container_id. A valid legacy
// line always ends in a bare stat type (c, g, ms, ...), never "c:<id>", so this
// check does not affect legacy multi-metric parsing.
usingDogStatsDContainerID := false
if idx := strings.LastIndex(elements[1], "|"); idx >= 0 {
if last := elements[1][idx+1:]; strings.HasPrefix(last, "c:") && len(last) > len("c:") {
usingDogStatsDContainerID = true
}
}

var samples []string
lineParts := strings.SplitN(elements[1], "|", 3)
if len(lineParts) < 2 {
Expand Down Expand Up @@ -258,8 +272,8 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
logger.Debug("bad line: invalid extended aggregate type", "line", line)
return events
}
} else if usingDogStatsDTags {
// disable multi-metrics
} else if usingDogStatsDTags || usingDogStatsDContainerID {
// disable multi-metrics for DogStatsD lines (|# tags and/or |c: container ID)
samples = elements[1:]
} else {
samples = strings.Split(elements[1], ":")
Expand Down
40 changes: 40 additions & 0 deletions pkg/line/line_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,46 @@ func TestLineToEvents(t *testing.T) {
},
},
},
"dogstatsd container ID without tags (counter)": {
in: "foo:100|c|c:container123",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo",
CValue: 100,
CLabels: map[string]string{"container_id": "container123"},
},
},
},
"dogstatsd container ID without tags (gauge)": {
in: "foo:50|g|c:gauge_container",
out: event.Events{
&event.GaugeEvent{
GMetricName: "foo",
GValue: 50,
GLabels: map[string]string{"container_id": "gauge_container"},
},
},
},
"dogstatsd container ID without tags (timer)": {
in: "foo:1000|ms|c:timer_container",
out: event.Events{
&event.ObserverEvent{
OMetricName: "foo",
OValue: 1,
OLabels: map[string]string{"container_id": "timer_container"},
},
},
},
"dogstatsd container ID without tags (complex value)": {
in: "foo:100|c|c:sha256:abcd1234efgh5678",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo",
CValue: 100,
CLabels: map[string]string{"container_id": "sha256:abcd1234efgh5678"},
},
},
},
"dogstatsd container ID with tags": {
in: "foo:100|c|#tag1:bar,tag2:baz|c:container456",
out: event.Events{
Expand Down