diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter.go b/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter.go index 08670311f98f4..7bf6c54154f23 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter.go +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter.go @@ -80,7 +80,11 @@ func (e *Exporter) ConsumeLogs(ctx context.Context, ld plog.Logs) (err error) { origin := message.NewOrigin(e.logSource) origin.SetTags(tags) origin.SetService(service) - origin.SetSource(e.logSource.Name) + if src, ok := ddLog.AdditionalProperties["datadog.log.source"]; ok { + origin.SetSource(src) + } else { + origin.SetSource(e.logSource.Name) + } content, err := ddLog.MarshalJSON() if err != nil { diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter_test.go b/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter_test.go index e7ef686b993f3..3944c650f7828 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter_test.go +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/logs_exporter_test.go @@ -72,6 +72,7 @@ func TestLogsExporter(t *testing.T) { lrr := testutil.GenerateLogsOneLogRecord() ldd := lrr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) ldd.Attributes().PutStr("message", "hello") + ldd.Attributes().PutStr("datadog.log.source", "custom_source") return lrr }(), otelSource: otelSource, @@ -83,6 +84,41 @@ func TestLogsExporter(t *testing.T) { "message": "hello", "app": "server", "instance_num": "1", + "datadog.log.source": "custom_source", + "@timestamp": testutil.TestLogTime.Format("2006-01-02T15:04:05.000Z07:00"), + "status": "Info", + "dd.span_id": fmt.Sprintf("%d", spanIDToUint64(ld.SpanID())), + "dd.trace_id": fmt.Sprintf("%d", traceIDToUint64(ld.TraceID())), + "otel.severity_text": "Info", + "otel.severity_number": "9", + "otel.span_id": spanIDToHexOrEmptyString(ld.SpanID()), + "otel.trace_id": traceIDToHexOrEmptyString(ld.TraceID()), + "otel.timestamp": fmt.Sprintf("%d", testutil.TestLogTime.UnixNano()), + "resource-attr": "resource-attr-val-1", + }, + }, + expectedTags: [][]string{{"otel_source:datadog_agent"}}, + }, + { + name: "resource-attribute-source", + args: args{ + ld: func() plog.Logs { + l := testutil.GenerateLogsOneLogRecord() + rl := l.ResourceLogs().At(0) + resourceAttrs := rl.Resource().Attributes() + resourceAttrs.PutStr("datadog.log.source", "custom_source_rattr") + return l + }(), + otelSource: otelSource, + logSourceName: LogSourceName, + }, + + want: testutil.JSONLogs{ + { + "message": "This is a log message", + "app": "server", + "instance_num": "1", + "datadog.log.source": "custom_source_rattr", "@timestamp": testutil.TestLogTime.Format("2006-01-02T15:04:05.000Z07:00"), "status": "Info", "dd.span_id": fmt.Sprintf("%d", spanIDToUint64(ld.SpanID())), @@ -186,7 +222,7 @@ func TestLogsExporter(t *testing.T) { return lrr }(), otelSource: "datadog_exporter", - logSourceName: "custom_source", + logSourceName: "", }, want: testutil.JSONLogs{ @@ -241,7 +277,11 @@ func TestLogsExporter(t *testing.T) { output := <-testChannel outputJSON := make(map[string]interface{}) json.Unmarshal(output.GetContent(), &outputJSON) - assert.Equal(t, tt.args.logSourceName, output.Origin.Source()) + if src, ok := outputJSON["datadog.log.source"]; ok { + assert.Equal(t, src, output.Origin.Source()) + } else { + assert.Equal(t, tt.args.logSourceName, output.Origin.Source()) + } assert.Equal(t, tt.expectedTags[i], output.Origin.Tags(nil)) ans = append(ans, outputJSON) } diff --git a/releasenotes/notes/mackjmr-otlp-log-source-f9bc51dcd803a238.yaml b/releasenotes/notes/mackjmr-otlp-log-source-f9bc51dcd803a238.yaml new file mode 100644 index 0000000000000..eb44689e78451 --- /dev/null +++ b/releasenotes/notes/mackjmr-otlp-log-source-f9bc51dcd803a238.yaml @@ -0,0 +1,11 @@ +# Each section from every release note are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +enhancements: + - | + Add support for setting a custom log source from resource attribute or log attribute `datadog.log.source`.