From 0eece159827c1e21fb9a803eb46fda53bb6689fd Mon Sep 17 00:00:00 2001 From: Michael Fulbright Date: Thu, 13 Mar 2025 12:12:01 -0400 Subject: [PATCH 1/2] fix(daemon): Properly escape UTF-8 in log labels The previous code did not account for that labels can contain UTF-8 characters which must be escaped. This commit changes the code to use the Go marshalling for json which will properly handle these characters. A guard was added to make sure invalid log labels are not converted to JSON (with an empty key or value). The ingest code should prevent this from happening but a secondary check here on JSON generation is a reasonable safeguard. --- daemon/internal/newrelic/log_events.go | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/daemon/internal/newrelic/log_events.go b/daemon/internal/newrelic/log_events.go index d927b4418..6f18c2fdb 100644 --- a/daemon/internal/newrelic/log_events.go +++ b/daemon/internal/newrelic/log_events.go @@ -76,21 +76,25 @@ func (events *LogEvents) CollectorJSON(id AgentRunID) ([]byte, error) { estimate := len(es) * 128 buf.Grow(estimate) buf.WriteString(`[{` + - `"common": {"attributes": {`) + `"common": {"attributes": `) nwrit := 0 - for _, value := range events.LogForwardingLabels { - if nwrit > 0 { - buf.WriteByte(',') + labelMap := make(map[string]string) + for _, label := range events.LogForwardingLabels { + // safegaurd against invalid labels + if len(label.LabelType) != 0 && len(label.LabelValue) != 0 { + labelMap["tags."+label.LabelType] = label.LabelValue } - nwrit++ - buf.WriteString(`"tags.`) - buf.WriteString(value.LabelType) - buf.WriteString(`":"`) - buf.WriteString(value.LabelValue) - buf.WriteString(`"`) } - buf.WriteString(`}},` + + j, e := json.Marshal(labelMap) + if e != nil { + log.Errorf("failed to marshal log label: %s", e) + buf.WriteString("{}") + } else { + buf.Write(j) + } + + buf.WriteString(`},` + `"logs": [`) nwrit = 0 From f0f45681ead50ee1d7bfa08dde5d3edd1092fdf8 Mon Sep 17 00:00:00 2001 From: Michael Fulbright Date: Thu, 13 Mar 2025 12:12:07 -0400 Subject: [PATCH 2/2] test(daemon): Adds test cases where label key or value is empty --- daemon/internal/newrelic/log_events_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon/internal/newrelic/log_events_test.go b/daemon/internal/newrelic/log_events_test.go index c0fb3d7d6..0f98e3132 100644 --- a/daemon/internal/newrelic/log_events_test.go +++ b/daemon/internal/newrelic/log_events_test.go @@ -27,6 +27,8 @@ var ( LogForwardingLabelsTestCase{name: "Invalid keys", labels: `[{"label_tipe":"type1","label_valyue":"value1"}]`, expected: `{}`}, LogForwardingLabelsTestCase{name: "Space in value", labels: `[{"label_type":"type1","label_value":"value 1"}]`, expected: `{"tags.type1":"value 1"}`}, LogForwardingLabelsTestCase{name: "Space in key", labels: `[{"label_type":"type 1","label_value":"value1"}]`, expected: `{"tags.type 1":"value1"}`}, + LogForwardingLabelsTestCase{name: "Empty value", labels: `[{"label_type":"type1","label_value":""}]`, expected: `{}`}, + LogForwardingLabelsTestCase{name: "Empty key", labels: `[{"label_type":"","label_value":"value1"}]`, expected: `{}`}, } )