From 7ce2e4ca2308e7805c54181e61458de24c0c7907 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Mon, 7 Feb 2022 12:10:38 -0800 Subject: [PATCH] OTLPLogExporter bug fix to handle null EventName (#2871) --- .../CHANGELOG.md | 11 ++- .../Implementation/LogRecordExtensions.cs | 6 +- .../OtlpLogExporterTests.cs | 75 +++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 41b14d77289..1a046e0b9d4 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -1,11 +1,10 @@ # Changelog -* Changed `OtlpLogExporter` to convert `ILogger` structured log inputs to - `Attributes` in OpenTelemetry (only active when `ParseStateValues` is `true` - on `OpenTelemetryLoggerOptions`) - ## Unreleased +* LogExporter bug fix to handle null EventName. + ([#2870](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2871)) + ## 1.2.0-rc2 Released 2022-Feb-02 @@ -14,6 +13,10 @@ Released 2022-Feb-02 .NET Core 3.x for gRPC-based exporting. ([#2691](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2691)) +* Changed `OtlpLogExporter` to convert `ILogger` structured log inputs to + `Attributes` in OpenTelemetry (only active when `ParseStateValues` is `true` + on `OpenTelemetryLoggerOptions`) + ## 1.2.0-rc1 Released 2021-Nov-29 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/LogRecordExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/LogRecordExtensions.cs index 0b60eeabce4..b797b2a79e7 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/LogRecordExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/LogRecordExtensions.cs @@ -85,9 +85,13 @@ internal static OtlpLogs.LogRecord ToOtlpLog(this LogRecord logRecord) } } - if (logRecord.EventId != default) + if (logRecord.EventId.Id != default) { otlpLogRecord.Attributes.AddIntAttribute(nameof(logRecord.EventId.Id), logRecord.EventId.Id); + } + + if (!string.IsNullOrEmpty(logRecord.EventId.Name)) + { otlpLogRecord.Attributes.AddStringAttribute(nameof(logRecord.EventId.Name), logRecord.EventId.Name); } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs new file mode 100644 index 00000000000..564e404076e --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -0,0 +1,75 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Logs; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests +{ + public class OtlpLogExporterTests : Http2UnencryptedSupportTests + { + [Fact] + public void ToOtlpLogRecordTest() + { + // Just a basic test to demonstrate an + // approach useful for testing. + // This needs to be expanded to + // actually test the conversion. + List logRecords = new List(); + + using var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddOpenTelemetry(options => + { + options.IncludeFormattedMessage = true; + options.ParseStateValues = true; + options.AddInMemoryExporter(logRecords); + }); + }); + + // TODO: + // Validate attributes, severity, traceid,spanid etc. + + var logger = loggerFactory.CreateLogger("log-category"); + logger.LogInformation("Hello from {name} {price}.", "tomato", 2.99); + Assert.Single(logRecords); + var logRecord = logRecords[0]; + var otlpLogRecord = logRecord.ToOtlpLog(); + Assert.NotNull(otlpLogRecord); + Assert.Equal("Hello from tomato 2.99.", otlpLogRecord.Body.StringValue); + logRecords.Clear(); + + logger.LogInformation(new EventId(10, null), "Hello from {name} {price}.", "tomato", 2.99); + Assert.Single(logRecords); + logRecord = logRecords[0]; + otlpLogRecord = logRecord.ToOtlpLog(); + Assert.NotNull(otlpLogRecord); + Assert.Equal("Hello from tomato 2.99.", otlpLogRecord.Body.StringValue); + logRecords.Clear(); + + logger.LogInformation(new EventId(10, "MyEvent10"), "Hello from {name} {price}.", "tomato", 2.99); + Assert.Single(logRecords); + logRecord = logRecords[0]; + otlpLogRecord = logRecord.ToOtlpLog(); + Assert.NotNull(otlpLogRecord); + Assert.Equal("Hello from tomato 2.99.", otlpLogRecord.Body.StringValue); + } + } +}