From 840434981b5fd0b995acc98403a92ad040a2a29e Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Wed, 7 Dec 2022 14:48:27 -0800 Subject: [PATCH] Fix ConsoleExporter fails silently when exporting an `ActivityLink` without Tags. (#3932) --- .../CHANGELOG.md | 4 ++ .../ConsoleActivityExporter.cs | 2 +- .../ConsoleActivityExporterTest.cs | 61 +++++++++++++++++++ ...penTelemetry.Exporter.Console.Tests.csproj | 3 + test/OpenTelemetry.Tests/Shared/Utils.cs | 6 +- 5 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Console.Tests/ConsoleActivityExporterTest.cs diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 4f202cb89..d4634bc50 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Bug fix, ConsoleExporter fails silently when exporting an `ActivityLink` + without Tags. + ([#3932](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3932)) + ## 1.4.0-beta.3 Released 2022-Nov-07 diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs index 068757841..c187046cb 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs @@ -115,7 +115,7 @@ namespace OpenTelemetry.Exporter foreach (var activityLink in activity.Links) { this.WriteLine($" {activityLink.Context.TraceId} {activityLink.Context.SpanId}"); - foreach (var attribute in activityLink.Tags) + foreach (ref readonly var attribute in activityLink.EnumerateTagObjects()) { if (ConsoleTagTransformer.Instance.TryTransformTag(attribute, out var result)) { diff --git a/test/OpenTelemetry.Exporter.Console.Tests/ConsoleActivityExporterTest.cs b/test/OpenTelemetry.Exporter.Console.Tests/ConsoleActivityExporterTest.cs new file mode 100644 index 000000000..d7400d3fe --- /dev/null +++ b/test/OpenTelemetry.Exporter.Console.Tests/ConsoleActivityExporterTest.cs @@ -0,0 +1,61 @@ +// +// 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.Diagnostics; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Exporter.Console.Tests; + +public class ConsoleActivityExporterTest +{ + [Fact] + public void VerifyConsoleActivityExporterDoesntFailWithoutActivityLinkTags() + { + var activitySourceName = Utils.GetCurrentMethodName(); + using var activitySource = new ActivitySource(activitySourceName); + + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(activitySourceName) + .AddInMemoryExporter(exportedItems) + .Build(); + + ActivityContext context; + using (var first = activitySource.StartActivity("first")) + { + context = first!.Context; + } + + exportedItems.Clear(); + + var links = new[] { new ActivityLink(context) }; + using (var secondActivity = activitySource.StartActivity(ActivityKind.Internal, links: links, name: "Second")) + { + } + + // Assert that an Activity was exported where ActivityLink.Tags == null. + var activity = exportedItems[0]; + Assert.Equal("Second", activity.DisplayName); + Assert.Null(activity.Links.First().Tags); + + // Test that the ConsoleExporter correctly handles an Activity without Tags. + using var consoleExporter = new ConsoleActivityExporter(new ConsoleExporterOptions()); + Assert.Equal(ExportResult.Success, consoleExporter.Export(new Batch(new[] { activity }, 1))); + } +} diff --git a/test/OpenTelemetry.Exporter.Console.Tests/OpenTelemetry.Exporter.Console.Tests.csproj b/test/OpenTelemetry.Exporter.Console.Tests/OpenTelemetry.Exporter.Console.Tests.csproj index 6a485d188..3a7ac3a71 100644 --- a/test/OpenTelemetry.Exporter.Console.Tests/OpenTelemetry.Exporter.Console.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Console.Tests/OpenTelemetry.Exporter.Console.Tests.csproj @@ -19,6 +19,9 @@ + + + diff --git a/test/OpenTelemetry.Tests/Shared/Utils.cs b/test/OpenTelemetry.Tests/Shared/Utils.cs index 43a6c1ee8..eb9697dcf 100644 --- a/test/OpenTelemetry.Tests/Shared/Utils.cs +++ b/test/OpenTelemetry.Tests/Shared/Utils.cs @@ -25,7 +25,11 @@ namespace OpenTelemetry.Tests public static string GetCurrentMethodName() { var method = new StackFrame(1).GetMethod(); - return $"{method.DeclaringType.FullName}.{method.Name}"; + + Debug.Assert(method != null, "Failed to get Method from the executing stack."); + Debug.Assert(method!.DeclaringType != null, "DeclaringType is not expected to be null."); + + return $"{method.DeclaringType!.FullName}.{method.Name}"; } } }