diff --git a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt index 7b02ca885de..94729fd41bd 100644 --- a/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/Stable/PublicAPI.Shipped.txt @@ -208,10 +208,10 @@ static OpenTelemetry.Baggage.operator !=(OpenTelemetry.Baggage left, OpenTelemet static OpenTelemetry.Baggage.operator ==(OpenTelemetry.Baggage left, OpenTelemetry.Baggage right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator !=(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool static OpenTelemetry.Context.Propagation.PropagationContext.operator ==(OpenTelemetry.Context.Propagation.PropagationContext left, OpenTelemetry.Context.Propagation.PropagationContext right) -> bool -static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity! activity) -> OpenTelemetry.Trace.Status -static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void -static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity! activity, System.Exception? ex) -> void -static OpenTelemetry.Trace.ActivityExtensions.SetStatus(this System.Diagnostics.Activity! activity, OpenTelemetry.Trace.Status status) -> void +static OpenTelemetry.Trace.ActivityExtensions.GetStatus(this System.Diagnostics.Activity? activity) -> OpenTelemetry.Trace.Status +static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex, in System.Diagnostics.TagList tags) -> void +static OpenTelemetry.Trace.ActivityExtensions.RecordException(this System.Diagnostics.Activity? activity, System.Exception? ex) -> void +static OpenTelemetry.Trace.ActivityExtensions.SetStatus(this System.Diagnostics.Activity? activity, OpenTelemetry.Trace.Status status) -> void static OpenTelemetry.Trace.Link.operator !=(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool static OpenTelemetry.Trace.Link.operator ==(OpenTelemetry.Trace.Link link1, OpenTelemetry.Trace.Link link2) -> bool static OpenTelemetry.Trace.SpanContext.implicit operator System.Diagnostics.ActivityContext(OpenTelemetry.Trace.SpanContext spanContext) -> System.Diagnostics.ActivityContext diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 458dff5ecc8..b3b2738a111 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -14,6 +14,17 @@ Notes](../../RELEASENOTES.md). * Optimize performance of `TraceContextPropagator.Extract`. ([#5749](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5749)) +* Obsoleted the `ActivityExtensions.GetStatus` and + `ActivityExtensions.SetStatus` extension methods. Users should migrate to the + `System.Diagnostics.DiagnosticSource` + [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API for setting the status and + [Activity.Status](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.status) + & + [Activity.StatusDescription](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.statusdescription) + APIs for reading the status of an `Activity` instance. + ([#5781](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5781)) + ## 1.9.0 Released 2024-Jun-14 diff --git a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs index d8ac769b9c9..a94a635055b 100644 --- a/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs +++ b/src/OpenTelemetry.Api/Trace/ActivityExtensions.cs @@ -21,17 +21,34 @@ public static class ActivityExtensions { /// /// Sets the status of activity execution. - /// Activity class in .NET does not support 'Status'. - /// This extension provides a workaround to store Status as special tags with key name of otel.status_code and otel.status_description. - /// Read more about SetStatus here https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status. /// + /// + /// Note: This method is obsolete. Call the + /// method instead. For more details see: . + /// /// Activity instance. /// Activity execution status. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SetStatus(this Activity activity, Status status) + [Obsolete("Call Activity.SetStatus instead this method will be removed in a future version.")] + public static void SetStatus(this Activity? activity, Status status) { if (activity != null) { + switch (status.StatusCode) + { + case StatusCode.Ok: + activity.SetStatus(ActivityStatusCode.Ok); + break; + case StatusCode.Unset: + activity.SetStatus(ActivityStatusCode.Unset); + break; + case StatusCode.Error: + activity.SetStatus(ActivityStatusCode.Error, status.Description); + break; + } + activity.SetTag(SpanAttributeConstants.StatusCodeKey, StatusHelper.GetTagValueForStatusCode(status.StatusCode)); activity.SetTag(SpanAttributeConstants.StatusDescriptionKey, status.Description); } @@ -39,21 +56,37 @@ public static void SetStatus(this Activity activity, Status status) /// /// Gets the status of activity execution. - /// Activity class in .NET does not support 'Status'. - /// This extension provides a workaround to retrieve Status from special tags with key name otel.status_code and otel.status_description. /// + /// + /// Note: This method is obsolete. Use the and + /// properties instead. For more + /// details see: . + /// /// Activity instance. /// Activity execution status. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Status GetStatus(this Activity activity) + [Obsolete("Use Activity.Status and Activity.StatusDescription instead this method will be removed in a future version.")] + public static Status GetStatus(this Activity? activity) { - if (activity == null - || !activity.TryGetStatus(out var statusCode, out var statusDescription)) + if (activity != null) { - return Status.Unset; + switch (activity.Status) + { + case ActivityStatusCode.Ok: + return Status.Ok; + case ActivityStatusCode.Error: + return new Status(StatusCode.Error, activity.StatusDescription); + } + + if (activity.TryGetStatus(out var statusCode, out var statusDescription)) + { + return new Status(statusCode, statusDescription); + } } - return new Status(statusCode, statusDescription); + return Status.Unset; } /// @@ -65,7 +98,7 @@ public static Status GetStatus(this Activity activity) /// "exception.stacktrace" is represented using the value of Exception.ToString. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RecordException(this Activity activity, Exception? ex) + public static void RecordException(this Activity? activity, Exception? ex) => RecordException(activity, ex, default); /// @@ -78,7 +111,7 @@ public static void RecordException(this Activity activity, Exception? ex) /// "exception.stacktrace" is represented using the value of Exception.ToString. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void RecordException(this Activity activity, Exception? ex, in TagList tags) + public static void RecordException(this Activity? activity, Exception? ex, in TagList tags) { if (ex == null || activity == null) { diff --git a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs index f70598d078b..cdae8d4292c 100644 --- a/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs +++ b/src/OpenTelemetry.Api/Trace/TelemetrySpan.cs @@ -47,7 +47,9 @@ public ActivitySpanId ParentSpanId /// Status to be set. public void SetStatus(Status value) { - this.Activity?.SetStatus(value); +#pragma warning disable + this.Activity.SetStatus(value); +#pragma warning restore } /// diff --git a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj index 645c9e49e59..e746024d006 100644 --- a/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj +++ b/src/OpenTelemetry.Shims.OpenTracing/OpenTelemetry.Shims.OpenTracing.csproj @@ -22,7 +22,9 @@ + + diff --git a/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs b/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs index 3473c4292ad..f3845519408 100644 --- a/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs +++ b/src/OpenTelemetry/Trace/Processor/ExceptionProcessor.cs @@ -62,11 +62,9 @@ public override void OnEnd(Activity activity) if (snapshot != pointers) { - // TODO: Remove this when SetStatus is deprecated +#pragma warning disable activity.SetStatus(Status.Error); - - // For processors/exporters checking `Status` property. - activity.SetStatus(ActivityStatusCode.Error); +#pragma warning restore } } } diff --git a/src/Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs index b237ccd5457..0540ce7c5ca 100644 --- a/src/Shared/ActivityHelperExtensions.cs +++ b/src/Shared/ActivityHelperExtensions.cs @@ -24,6 +24,7 @@ internal static class ActivityHelperExtensions /// Status description. /// if was found on the supplied Activity. [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Obsolete] public static bool TryGetStatus(this Activity activity, out StatusCode statusCode, out string? statusDescription) { Debug.Assert(activity != null, "Activity should not be null"); diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index 029a3c2451c..b3e43d5bc9f 100644 --- a/src/Shared/AssemblyVersionExtensions.cs +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -4,6 +4,7 @@ #nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace OpenTelemetry.Internal; @@ -11,6 +12,33 @@ namespace OpenTelemetry.Internal; internal static class AssemblyVersionExtensions { public static string GetPackageVersion(this Assembly assembly) + { + Debug.Assert(assembly != null, "assembly was null"); + + var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; + + Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); + + return ParsePackageVersion(informationalVersion!); + } + + public static bool TryGetPackageVersion(this Assembly assembly, [NotNullWhen(true)] out string? packageVersion) + { + Debug.Assert(assembly != null, "assembly was null"); + + var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; + + if (string.IsNullOrEmpty(informationalVersion)) + { + packageVersion = null; + return false; + } + + packageVersion = ParsePackageVersion(informationalVersion!); + return true; + } + + private static string ParsePackageVersion(string informationalVersion) { // MinVer https://github.com/adamralph/minver?tab=readme-ov-file#version-numbers // together with Microsoft.SourceLink.GitHub https://github.com/dotnet/sourcelink @@ -20,9 +48,6 @@ public static string GetPackageVersion(this Assembly assembly) // The following parts are optional: pre-release label, pre-release version, git height, Git SHA of current commit // For package version, value of AssemblyInformationalVersionAttribute without commit hash is returned. - var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; - Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); - var indexOfPlusSign = informationalVersion!.IndexOf('+'); return indexOfPlusSign > 0 ? informationalVersion.Substring(0, indexOfPlusSign) diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index 4800f76a845..b3769fc1459 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -1,8 +1,9 @@ - + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 84d3076500a..9f5da4cd8d7 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -370,7 +370,8 @@ public void ToOtlpSpanTest() links: childLinks); Assert.NotNull(childActivity); - childActivity.SetStatus(Status.Error); + + childActivity.SetStatus(ActivityStatusCode.Error); var childEvents = new List { new("e0"), new("e1", default, new ActivityTagsCollection(attributes)) }; childActivity.AddEvent(childEvents[0]); @@ -388,7 +389,8 @@ public void ToOtlpSpanTest() Assert.Equal(traceId, otlpSpan.TraceId); Assert.Equal(parentId, otlpSpan.ParentSpanId); - // Assert.Equal(OtlpTrace.Status.Types.StatusCode.NotFound, otlpSpan.Status.Code); + Assert.NotNull(otlpSpan.Status); + Assert.Equal(OtlpTrace.Status.Types.StatusCode.Error, otlpSpan.Status.Code); Assert.Equal(Status.Error.Description ?? string.Empty, otlpSpan.Status.Message); Assert.Empty(otlpSpan.Attributes); @@ -474,6 +476,7 @@ public void ToOtlpSpanNativeActivityStatusTest(ActivityStatusCode expectedStatus [InlineData(StatusCode.Unset, "Unset", "Description will be ignored if status is Unset.")] [InlineData(StatusCode.Ok, "Ok", "Description must only be used with the Error StatusCode.")] [InlineData(StatusCode.Error, "Error", "Error description.")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanStatusTagTest(StatusCode expectedStatusCode, string statusCodeTagValue, string statusDescription) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -502,6 +505,7 @@ public void ToOtlpSpanStatusTagTest(StatusCode expectedStatusCode, string status [InlineData(StatusCode.Unset, "uNsET")] [InlineData(StatusCode.Ok, "oK")] [InlineData(StatusCode.Error, "ERROR")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanStatusTagIsCaseInsensitiveTest(StatusCode expectedStatusCode, string statusCodeTagValue) { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -517,6 +521,7 @@ public void ToOtlpSpanStatusTagIsCaseInsensitiveTest(StatusCode expectedStatusCo } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivityStatusCodeIsOk() { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); @@ -536,6 +541,7 @@ public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivitySta } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivityStatusCodeIsError() { using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs index da6cdcbfcbb..bfe69520fea 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionTest.cs @@ -79,6 +79,7 @@ public void ToZipkinSpan_NoEvents() [InlineData(StatusCode.Ok, "Ok")] [InlineData(StatusCode.Error, "ERROR")] [InlineData(StatusCode.Unset, "iNvAlId")] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ToZipkinSpan_Status_ErrorFlagTest(StatusCode expectedStatusCode, string statusCodeTagValue) { // Arrange @@ -159,6 +160,7 @@ public void ToZipkinSpan_Activity_Status_And_StatusDescription_is_Set(ActivitySt } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsOk() { // Arrange. @@ -184,6 +186,7 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError() { // Arrange. @@ -219,6 +222,7 @@ public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeI } [Fact] + [Obsolete("Remove when ActivityExtensions status APIs are removed")] public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError_SettingTagFirst() { // Arrange. diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index 01e40b66b16..b1481ac0541 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -322,31 +322,18 @@ public void UpdatesServiceNameFromIConfiguration() [InlineData(false, false, false)] [InlineData(false, true, false)] [InlineData(false, false, true)] - [InlineData(false, false, false, StatusCode.Ok)] - [InlineData(false, false, false, StatusCode.Ok, null, true)] - [InlineData(false, false, false, StatusCode.Error)] - [InlineData(false, false, false, StatusCode.Error, "Error description")] + [InlineData(false, false, false, ActivityStatusCode.Ok)] + [InlineData(false, false, false, ActivityStatusCode.Ok, null, true)] + [InlineData(false, false, false, ActivityStatusCode.Error)] + [InlineData(false, false, false, ActivityStatusCode.Error, "Error description")] public void IntegrationTest( bool useShortTraceIds, bool useTestResource, bool isRootSpan, - StatusCode statusCode = StatusCode.Unset, + ActivityStatusCode statusCode = ActivityStatusCode.Unset, string statusDescription = null, bool addErrorTag = false) { - var status = statusCode switch - { - StatusCode.Unset => Status.Unset, - StatusCode.Ok => Status.Ok, - StatusCode.Error => Status.Error, - _ => throw new InvalidOperationException(), - }; - - if (!string.IsNullOrEmpty(statusDescription)) - { - status = status.WithDescription(statusDescription); - } - Guid requestId = Guid.NewGuid(); ZipkinExporter exporter = new ZipkinExporter( @@ -360,7 +347,7 @@ public void IntegrationTest( .Where(pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).FirstOrDefault().Value; var resourceTags = string.Empty; var dateTime = DateTime.UtcNow; - var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status, dateTime: dateTime); + var activity = CreateTestActivity(isRootSpan: isRootSpan, statusCode: statusCode, statusDescription: statusDescription, dateTime: dateTime); if (useTestResource) { serviceName = "MyService"; @@ -409,13 +396,13 @@ public void IntegrationTest( string errorTag = string.Empty; switch (statusCode) { - case StatusCode.Ok: + case ActivityStatusCode.Ok: statusTag = $@"""{SpanAttributeConstants.StatusCodeKey}"":""OK"","; break; - case StatusCode.Unset: + case ActivityStatusCode.Unset: statusTag = string.Empty; break; - case StatusCode.Error: + case ActivityStatusCode.Error: statusTag = $@"""{SpanAttributeConstants.StatusCodeKey}"":""ERROR"","; errorTag = $@"""{ZipkinActivityConversionExtensions.ZipkinErrorFlagTagName}"":""{statusDescription}"","; break; @@ -464,7 +451,8 @@ internal static Activity CreateTestActivity( bool addLinks = true, Resource resource = null, ActivityKind kind = ActivityKind.Client, - Status? status = null, + ActivityStatusCode statusCode = ActivityStatusCode.Unset, + string statusDescription = null, DateTime? dateTime = null) { var startTimestamp = DateTime.UtcNow; @@ -552,10 +540,7 @@ internal static Activity CreateTestActivity( } } - if (status.HasValue) - { - activity.SetStatus(status.Value); - } + activity.SetStatus(statusCode, statusDescription); activity.SetEndTime(endTimestamp); activity.Stop(); diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj index 07fe011a082..1aac45f10ca 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/OpenTelemetry.Shims.OpenTracing.Tests.csproj @@ -2,16 +2,16 @@ Unit test project for OpenTelemetry.Shims.OpenTracing $(TargetFrameworksForTests) + $(DefineConstants);BUILDING_USING_PROJECTS disable + - - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs index ce546c868bf..a3a58facfd9 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanBuilderShimTests.cs @@ -216,8 +216,18 @@ public void WithTag_KeyIsErrorStringValue() // build var spanShim = (SpanShim)shim.Start(); - // Span status should be set - Assert.Equal(Status.Error, spanShim.Span.Activity.GetStatus()); + // Legacy span status tag should be set + Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, spanShim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, spanShim.Span.Activity.Status); + } } [Fact] @@ -262,8 +272,18 @@ public void WithTag_KeyIsErrorBoolValue() // build var spanShim = (SpanShim)shim.Start(); - // Span status should be set - Assert.Equal(Status.Error, spanShim.Span.Activity.GetStatus()); + // Legacy span status tag should be set + Assert.Equal("ERROR", spanShim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, spanShim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, spanShim.Span.Activity.Status); + } } [Fact] diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs index 80178f405be..9911d9f76fc 100644 --- a/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/SpanShimTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using OpenTelemetry.Trace; using OpenTracing.Tag; using Xunit; @@ -209,10 +210,34 @@ public void SetTagBoolValue() Assert.True((bool)shim.Span.Activity.TagObjects.First().Value); // A boolean tag named "error" is a special case that must be checked - Assert.Equal(Status.Error, shim.Span.Activity.GetStatus()); + + // Legacy span status tag should be set + Assert.Equal("ERROR", shim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Error, shim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, shim.Span.Activity.Status); + } shim.SetTag(Tags.Error.Key, false); - Assert.Equal(Status.Ok, shim.Span.Activity.GetStatus()); + + // Legacy span status tag should be set + Assert.Equal("OK", shim.Span.Activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + + if (VersionHelper.IsApiVersionGreaterThanOrEqualTo(1, 10)) + { + // Activity status code should also be set + Assert.Equal(ActivityStatusCode.Ok, shim.Span.Activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, shim.Span.Activity.Status); + } } [Fact] @@ -245,27 +270,6 @@ public void SetTagDoubleValue() Assert.Equal(1, (double)shim.Span.Activity.TagObjects.First().Value); } - [Fact] - public void SetTagBooleanTagValue() - { - var tracer = TracerProvider.Default.GetTracer(TracerName); - var shim = new SpanShim(tracer.StartSpan(SpanName)); - - Assert.Throws(() => shim.SetTag((BooleanTag)null, true)); - - shim.SetTag(new BooleanTag("foo"), true); - shim.SetTag(new BooleanTag(Tags.Error.Key), true); - - Assert.Equal("foo", shim.Span.Activity.TagObjects.First().Key); - Assert.True((bool)shim.Span.Activity.TagObjects.First().Value); - - // A boolean tag named "error" is a special case that must be checked - Assert.Equal(Status.Error, shim.Span.Activity.GetStatus()); - - shim.SetTag(Tags.Error.Key, false); - Assert.Equal(Status.Ok, shim.Span.Activity.GetStatus()); - } - [Fact] public void SetTagStringTagValue() { diff --git a/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs new file mode 100644 index 00000000000..57b1b8a9f53 --- /dev/null +++ b/test/OpenTelemetry.Shims.OpenTracing.Tests/VersionHelper.cs @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using NuGet.Versioning; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Shims.OpenTracing.Tests; + +internal static class VersionHelper +{ +#if BUILDING_USING_PROJECTS + private static NuGetVersion? apiVersion = new(100, 0, 0); +#else + private static NuGetVersion? apiVersion; +#endif + + public static NuGetVersion ApiVersion + { + get + { + return apiVersion ??= ResolveApiVersion(); + + static NuGetVersion ResolveApiVersion() + { + if (!typeof(TracerProvider).Assembly.TryGetPackageVersion(out var packageVersion)) + { + throw new InvalidOperationException("OpenTelemetry.Api package version could not be resolved"); + } + + return NuGetVersion.Parse(packageVersion); + } + } + } + + public static bool IsApiVersionGreaterThanOrEqualTo(int major, int minor) + { + return ApiVersion >= new NuGetVersion(major, minor, 0); + } +}