[api] Mark SetStatus & GetStatus ActivityExtensions obsolete (#5781)

Co-authored-by: Vishwesh Bankwar <vishweshbankwar@users.noreply.github.com>
Co-authored-by: Mikel Blanchard <mblanchard@macrosssoftware.com>
This commit is contained in:
Yevhenii Solomchenko 2024-08-22 00:08:29 +02:00 committed by GitHub
parent c483222ea5
commit 1b3f1894d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 219 additions and 85 deletions

View File

@ -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

View File

@ -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

View File

@ -21,17 +21,34 @@ public static class ActivityExtensions
{
/// <summary>
/// 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.
/// </summary>
/// <remarks>
/// Note: This method is obsolete. Call the <see cref="Activity.SetStatus"/>
/// method instead. For more details see: <see
/// href="https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api#setting-status"
/// />.
/// </remarks>
/// <param name="activity">Activity instance.</param>
/// <param name="status">Activity execution status.</param>
[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 class ActivityExtensions
/// <summary>
/// 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.
/// </summary>
/// <remarks>
/// Note: This method is obsolete. Use the <see cref="Activity.Status"/> and
/// <see cref="Activity.StatusDescription"/> properties instead. For more
/// details see: <see
/// href="https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api#setting-status"
/// />.
/// </remarks>
/// <param name="activity">Activity instance.</param>
/// <returns>Activity execution status.</returns>
[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;
}
/// <summary>
@ -65,7 +98,7 @@ public static class ActivityExtensions
/// "exception.stacktrace" is represented using the value of <a href="https://learn.microsoft.com/dotnet/api/system.exception.tostring">Exception.ToString</a>.
/// </remarks>
[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);
/// <summary>
@ -78,7 +111,7 @@ public static class ActivityExtensions
/// "exception.stacktrace" is represented using the value of <a href="https://learn.microsoft.com/dotnet/api/system.exception.tostring">Exception.ToString</a>.
/// </remarks>
[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)
{

View File

@ -47,7 +47,9 @@ public class TelemetrySpan : IDisposable
/// <param name="value">Status to be set.</param>
public void SetStatus(Status value)
{
this.Activity?.SetStatus(value);
#pragma warning disable
this.Activity.SetStatus(value);
#pragma warning restore
}
/// <summary>

View File

@ -22,7 +22,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="$(RepoRoot)\src\Shared\AssemblyVersionExtensions.cs" Link="Includes\AssemblyVersionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Shims\NullableAttributes.cs" Link="Includes\Shims\NullableAttributes.cs" />
</ItemGroup>
</Project>

View File

@ -62,11 +62,9 @@ internal sealed class ExceptionProcessor : BaseProcessor<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
}
}
}

View File

@ -24,6 +24,7 @@ internal static class ActivityHelperExtensions
/// <param name="statusDescription">Status description.</param>
/// <returns><see langword="true"/> if <see cref="Status"/> was found on the supplied Activity.</returns>
[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");

View File

@ -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<AssemblyInformationalVersionAttribute>()?.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<AssemblyInformationalVersionAttribute>()?.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 @@ internal static class AssemblyVersionExtensions
// 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<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly");
var indexOfPlusSign = informationalVersion!.IndexOf('+');
return indexOfPlusSign > 0
? informationalVersion.Substring(0, indexOfPlusSign)

View File

@ -1,8 +1,9 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
<ItemGroup>
<PackageVersion Update="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
<PackageVersion Update="System.Text.Json" Version="8.0.4" />
<PackageVersion Include="NuGet.Versioning" Version="6.11.0" />
<PackageVersion Include="Microsoft.Coyote" Version="1.7.10" />
</ItemGroup>
</Project>

View File

@ -370,7 +370,8 @@ public class OtlpTraceExporterTests
links: childLinks);
Assert.NotNull(childActivity);
childActivity.SetStatus(Status.Error);
childActivity.SetStatus(ActivityStatusCode.Error);
var childEvents = new List<ActivityEvent> { new("e0"), new("e1", default, new ActivityTagsCollection(attributes)) };
childActivity.AddEvent(childEvents[0]);
@ -388,7 +389,8 @@ public class OtlpTraceExporterTests
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 class OtlpTraceExporterTests
[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 class OtlpTraceExporterTests
[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 class OtlpTraceExporterTests
}
[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 class OtlpTraceExporterTests
}
[Fact]
[Obsolete("Remove when ActivityExtensions status APIs are removed")]
public void ToOtlpSpanActivityStatusTakesPrecedenceOverStatusTagsWhenActivityStatusCodeIsError()
{
using var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest));

View File

@ -79,6 +79,7 @@ public class ZipkinActivityConversionTest
[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 class ZipkinActivityConversionTest
}
[Fact]
[Obsolete("Remove when ActivityExtensions status APIs are removed")]
public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsOk()
{
// Arrange.
@ -184,6 +186,7 @@ public class ZipkinActivityConversionTest
}
[Fact]
[Obsolete("Remove when ActivityExtensions status APIs are removed")]
public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError()
{
// Arrange.
@ -219,6 +222,7 @@ public class ZipkinActivityConversionTest
}
[Fact]
[Obsolete("Remove when ActivityExtensions status APIs are removed")]
public void ActivityStatus_Takes_precedence_Over_Status_Tags_ActivityStatusCodeIsError_SettingTagFirst()
{
// Arrange.

View File

@ -322,31 +322,18 @@ public class ZipkinExporterTests : IDisposable
[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 class ZipkinExporterTests : IDisposable
.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 class ZipkinExporterTests : IDisposable
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 @@ public class ZipkinExporterTests : IDisposable
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 @@ public class ZipkinExporterTests : IDisposable
}
}
if (status.HasValue)
{
activity.SetStatus(status.Value);
}
activity.SetStatus(statusCode, statusDescription);
activity.SetEndTime(endTimestamp);
activity.Stop();

View File

@ -2,16 +2,16 @@
<PropertyGroup>
<Description>Unit test project for OpenTelemetry.Shims.OpenTracing</Description>
<TargetFrameworks>$(TargetFrameworksForTests)</TargetFrameworks>
<DefineConstants Condition="'$(RunningDotNetPack)' != 'true'">$(DefineConstants);BUILDING_USING_PROJECTS</DefineConstants>
<!-- this is temporary. will remove in future PR. -->
<Nullable>disable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NuGet.Versioning"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>

View File

@ -216,8 +216,18 @@ public class SpanBuilderShimTests
// 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 class SpanBuilderShimTests
// 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]

View File

@ -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 class SpanShimTests
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 class SpanShimTests
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<ArgumentNullException>(() => 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()
{

View File

@ -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);
}
}