diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index a1852a68e2..cad40dcf22 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -6,6 +6,15 @@ `RegisterPayloadTransmittedCallback` API. ([#1309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1309)) +* Added support for sending `LogRecord.Body` as common schema `body` if + `{OriginalFormat}` key is not found. + ([#1321](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1321)) + +* Added support for sending `LogRecord.FormattedMessage` (if set) as common + schema `formattedMessage` if it differs from the detected template (either + `{OriginalFormat}` key or `LogRecord.Body`). + ([#1321](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1321)) + ## 1.5.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 9ca6abf692..7c4f80351d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -28,6 +28,7 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText SeverityTextProperty = JsonEncodedText.Encode("severityText"); private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); + private static readonly JsonEncodedText FormattedMessageProperty = JsonEncodedText.Encode("formattedMessage"); private static readonly JsonEncodedText DistributedTraceExtensionProperty = JsonEncodedText.Encode("dt"); private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); @@ -131,7 +132,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WriteString(SeverityTextProperty, LogLevelToSeverityTextMappings[logLevel]); writer.WriteNumber(SeverityNumberProperty, LogLevelToSeverityNumberMappings[logLevel]); - string? body = null; + string? originalFormat = null; if (item.Attributes != null) { @@ -146,7 +147,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C if (attribute.Key == "{OriginalFormat}") { - body = attribute.Value as string; + originalFormat = attribute.Value as string; continue; } @@ -160,13 +161,29 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C } } - if (!string.IsNullOrEmpty(body)) + var hasBody = false; + + if (!string.IsNullOrEmpty(originalFormat)) + { + writer.WriteString(BodyProperty, originalFormat); + hasBody = true; + } + else if (!string.IsNullOrEmpty(item.Body)) { - writer.WriteString(BodyProperty, body); + writer.WriteString(BodyProperty, item.Body); + hasBody = true; } else if (!string.IsNullOrEmpty(item.FormattedMessage)) { writer.WriteString(BodyProperty, item.FormattedMessage); + writer.WriteString(FormattedMessageProperty, item.FormattedMessage); + } + + if (hasBody + && !string.IsNullOrEmpty(item.FormattedMessage) + && item.Body != item.FormattedMessage) + { + writer.WriteString(FormattedMessageProperty, item.FormattedMessage); } SerializeResourceToJsonInsideCurrentObject(resource, serializationState); @@ -184,8 +201,9 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w { var hasTraceContext = item.TraceId != default; var hasException = item.Exception != null; + var hasExtensions = serializationState.ExtensionAttributeCount > 0; - if (!hasTraceContext && !hasException && serializationState.ExtensionAttributeCount <= 0) + if (!hasTraceContext && !hasException && !hasExtensions) { return; } @@ -215,7 +233,10 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w writer.WriteEndObject(); } - serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); + if (hasExtensions) + { + serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); + } writer.WriteEndObject(); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 80a1894ada..cabe61439a 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -119,7 +119,21 @@ public void LogRecordOriginalFormatBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\"}}}}\n", + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", + json); + } + + [Fact] + public void LogRecordBodyJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.Body = "hello world"; + logRecord.FormattedMessage = "goodbye world"; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", json); } @@ -132,7 +146,7 @@ public void LogRecordFormattedMessageBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\"}}}}\n", + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\",\"formattedMessage\":\"goodbye world\"}}}}\n", json); }