Skip to content

Commit

Permalink
Add Support for HttpSemanticConvention breaking changes. (#4504)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyMothra authored May 24, 2023
1 parent f4f4469 commit 47d88e1
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/OpenTelemetry.Api/Internal/HttpSemanticConventionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// <copyright file="HttpSemanticConventionHelper.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

namespace OpenTelemetry.Internal;

/// <summary>
/// Helper class for Http Semantic Conventions.
/// </summary>
/// <remarks>
/// Due to a breaking change in the semantic convention, affected instrumentation libraries
/// must inspect an environment variable to determine which attributes to emit.
/// This is expected to be removed when the instrumentation libraries reach Stable.
/// <see href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md"/>.
/// </remarks>
internal static class HttpSemanticConventionHelper
{
[Flags]
internal enum HttpSemanticConvention
{
/// <summary>
/// Instructs an instrumentation library to emit the old experimental HTTP attributes.
/// </summary>
Old = 0x1,

/// <summary>
/// Instructs an instrumentation library to emit the new, stable Http attributes.
/// </summary>
New = 0x2,

/// <summary>
/// Instructs an instrumentation library to emit both the old and new attributes.
/// </summary>
Dupe = Old | New,
}

public static HttpSemanticConvention GetSemanticConventionOptIn()
{
try
{
var envVarValue = Environment.GetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN");
return envVarValue?.ToLowerInvariant() switch
{
"http" => HttpSemanticConvention.New,
"http/dup" => HttpSemanticConvention.Dupe,
_ => HttpSemanticConvention.Old,
};
}
catch
{
return HttpSemanticConvention.Old;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#endif
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
{
Expand Down Expand Up @@ -62,13 +63,16 @@ internal class HttpInListener : ListenerHandler
#endif
private readonly PropertyFetcher<Exception> stopExceptionFetcher = new("Exception");
private readonly AspNetCoreInstrumentationOptions options;
private readonly HttpSemanticConvention httpSemanticConvention;

public HttpInListener(AspNetCoreInstrumentationOptions options)
: base(DiagnosticSourceName)
{
Guard.ThrowIfNull(options);

this.options = options;

this.httpSemanticConvention = GetSemanticConventionOptIn();
}

public override void OnEventWritten(string name, object payload)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\GrpcTagHelper.cs" Link="Includes\GrpcTagHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\StatusCanonicalCode.cs" Link="Includes\StatusCanonicalCode.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\HttpSemanticConventionHelper.cs" Link="Includes\HttpSemanticConventionHelper.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// <copyright file="HttpSemanticConventionHelperTest.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

using Xunit;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Api.Tests.Internal;

public class HttpSemanticConventionHelperTest
{
[Fact]
public void VerifyFlags()
{
var testValue = HttpSemanticConvention.Dupe;
Assert.True(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.True(testValue.HasFlag(HttpSemanticConvention.New));

testValue = HttpSemanticConvention.Old;
Assert.True(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.False(testValue.HasFlag(HttpSemanticConvention.New));

testValue = HttpSemanticConvention.New;
Assert.False(testValue.HasFlag(HttpSemanticConvention.Old));
Assert.True(testValue.HasFlag(HttpSemanticConvention.New));
}

[Fact]
public void VerifyGetSemanticConventionOptIn()
{
this.RunTestWithEnvironmentVariable(null, HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable(string.Empty, HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("junk", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("none", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("NONE", HttpSemanticConvention.Old);
this.RunTestWithEnvironmentVariable("http", HttpSemanticConvention.New);
this.RunTestWithEnvironmentVariable("HTTP", HttpSemanticConvention.New);
this.RunTestWithEnvironmentVariable("http/dup", HttpSemanticConvention.Dupe);
this.RunTestWithEnvironmentVariable("HTTP/DUP", HttpSemanticConvention.Dupe);
}

private void RunTestWithEnvironmentVariable(string value, HttpSemanticConvention expected)
{
try
{
Environment.SetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN", value);

Assert.Equal(expected, GetSemanticConventionOptIn());
}
finally
{
Environment.SetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN", null);
}
}
}

0 comments on commit 47d88e1

Please sign in to comment.