diff --git a/Directory.Packages.props b/Directory.Packages.props
index 626320dbe96..f7775366744 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -13,6 +13,7 @@
+
diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln
index 7c75ed0c9b2..b6fbf4d3081 100644
--- a/OpenTelemetry.sln
+++ b/OpenTelemetry.sln
@@ -267,6 +267,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC}"
ProjectSection(SolutionItems) = preProject
src\Shared\ActivityInstrumentationHelper.cs = src\Shared\ActivityInstrumentationHelper.cs
+ src\Shared\HttpSemanticConventionHelper.cs = src\Shared\HttpSemanticConventionHelper.cs
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DiagnosticSourceInstrumentation", "DiagnosticSourceInstrumentation", "{28F3EC79-660C-4659-8B73-F90DC1173316}"
@@ -336,10 +337,6 @@ Global
{A38AC295-2745-4B85-8B6B-DCA864CEDD5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A38AC295-2745-4B85-8B6B-DCA864CEDD5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A38AC295-2745-4B85-8B6B-DCA864CEDD5B}.Release|Any CPU.Build.0 = Release|Any CPU
- {56A34828-621A-478B-A0B8-C065FE938383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {56A34828-621A-478B-A0B8-C065FE938383}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {56A34828-621A-478B-A0B8-C065FE938383}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {56A34828-621A-478B-A0B8-C065FE938383}.Release|Any CPU.Build.0 = Release|Any CPU
{1AFFF251-3B0C-47CA-BE94-937083732C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AFFF251-3B0C-47CA-BE94-937083732C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AFFF251-3B0C-47CA-BE94-937083732C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -356,10 +353,6 @@ Global
{305E9DFD-E73B-4A28-8769-795C25551020}.Debug|Any CPU.Build.0 = Debug|Any CPU
{305E9DFD-E73B-4A28-8769-795C25551020}.Release|Any CPU.ActiveCfg = Release|Any CPU
{305E9DFD-E73B-4A28-8769-795C25551020}.Release|Any CPU.Build.0 = Release|Any CPU
- {98F9556B-116F-49B5-9211-BB1D418446FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {98F9556B-116F-49B5-9211-BB1D418446FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {98F9556B-116F-49B5-9211-BB1D418446FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {98F9556B-116F-49B5-9211-BB1D418446FF}.Release|Any CPU.Build.0 = Release|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF3E6E08-E8E4-4523-B526-847CD989279F}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs
index 283126e488a..cca902e2c74 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationOptions.cs
@@ -16,6 +16,8 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.AspNetCore
{
@@ -24,6 +26,23 @@ namespace OpenTelemetry.Instrumentation.AspNetCore
///
public class AspNetCoreInstrumentationOptions
{
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AspNetCoreInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal AspNetCoreInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+
///
/// Gets or sets a filter function that determines whether or not to
/// collect telemetry on a per request basis.
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs
index 23abdeec670..4b2bbb0cb31 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs
@@ -16,6 +16,8 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.AspNetCore
{
@@ -24,6 +26,23 @@ namespace OpenTelemetry.Instrumentation.AspNetCore
///
public class AspNetCoreMetricsInstrumentationOptions
{
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AspNetCoreMetricsInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal AspNetCoreMetricsInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+
///
/// Delegate for enrichment of recorded metric with additional tags.
///
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
index 809473ad3aa..bbf749d5414 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs
@@ -63,7 +63,6 @@ internal class HttpInListener : ListenerHandler
#endif
private readonly PropertyFetcher stopExceptionFetcher = new("Exception");
private readonly AspNetCoreInstrumentationOptions options;
- private readonly HttpSemanticConvention httpSemanticConvention;
public HttpInListener(AspNetCoreInstrumentationOptions options)
: base(DiagnosticSourceName)
@@ -71,8 +70,6 @@ public HttpInListener(AspNetCoreInstrumentationOptions options)
Guard.ThrowIfNull(options);
this.options = options;
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
}
public override void OnEventWritten(string name, object payload)
@@ -198,7 +195,7 @@ public void OnStartActivity(Activity activity, object payload)
activity.DisplayName = path;
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
if (request.Host.HasValue)
{
@@ -227,7 +224,7 @@ public void OnStartActivity(Activity activity, object payload)
}
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
if (request.Host.HasValue)
{
@@ -284,12 +281,12 @@ public void OnStopActivity(Activity activity, object payload)
var response = context.Response;
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
activity.SetTag(SemanticConventions.AttributeHttpStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode));
}
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode));
}
@@ -488,12 +485,12 @@ private void AddGrpcAttributes(Activity activity, string grpcMethod, HttpContext
activity.SetTag(SemanticConventions.AttributeNetPeerIp, context.Connection.RemoteIpAddress.ToString());
}
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
activity.SetTag(SemanticConventions.AttributeNetPeerPort, context.Connection.RemotePort);
}
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
activity.SetTag(SemanticConventions.AttributeServerPort, context.Connection.RemotePort);
}
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs
index 17d9e77738e..981d4bc26b0 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs
@@ -35,16 +35,12 @@ internal sealed class HttpInMetricsListener : ListenerHandler
private readonly AspNetCoreMetricsInstrumentationOptions options;
private readonly Histogram httpServerDuration;
- private readonly HttpSemanticConvention httpSemanticConvention;
-
internal HttpInMetricsListener(string name, Meter meter, AspNetCoreMetricsInstrumentationOptions options)
: base(name)
{
this.meter = meter;
this.options = options;
this.httpServerDuration = meter.CreateHistogram(HttpServerDurationMetricName, "ms", "Measures the duration of inbound HTTP requests.");
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
}
public override void OnEventWritten(string name, object payload)
@@ -83,7 +79,7 @@ public override void OnEventWritten(string name, object payload)
TagList tags = default;
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol)));
tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpScheme, context.Request.Scheme));
@@ -102,7 +98,7 @@ public override void OnEventWritten(string name, object payload)
}
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol)));
tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme));
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs
index 47cbcdf3fc0..59d65896635 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs
@@ -66,10 +66,15 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation(
name ??= Options.DefaultName;
- if (configureAspNetCoreInstrumentationOptions != null)
+ builder.ConfigureServices(services =>
{
- builder.ConfigureServices(services => services.Configure(name, configureAspNetCoreInstrumentationOptions));
- }
+ if (configureAspNetCoreInstrumentationOptions != null)
+ {
+ services.Configure(name, configureAspNetCoreInstrumentationOptions);
+ }
+
+ services.RegisterOptionsFactory(configuration => new AspNetCoreMetricsInstrumentationOptions(configuration));
+ });
builder.AddMeter(AspNetCoreMetrics.InstrumentationName);
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj
index f2881a4ca1e..262e88c8c63 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj
@@ -14,7 +14,9 @@
-
+
+
+
diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs
index fde28c82ad5..b8872d5912d 100644
--- a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs
@@ -68,10 +68,15 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation(
name ??= Options.DefaultName;
- if (configureAspNetCoreInstrumentationOptions != null)
+ builder.ConfigureServices(services =>
{
- builder.ConfigureServices(services => services.Configure(name, configureAspNetCoreInstrumentationOptions));
- }
+ if (configureAspNetCoreInstrumentationOptions != null)
+ {
+ services.Configure(name, configureAspNetCoreInstrumentationOptions);
+ }
+
+ services.RegisterOptionsFactory(configuration => new AspNetCoreInstrumentationOptions(configuration));
+ });
if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder)
{
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentationOptions.cs
index d03c882aa6f..4ea44b69e59 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentationOptions.cs
@@ -15,6 +15,8 @@
//
using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.GrpcNetClient
{
@@ -23,6 +25,23 @@ namespace OpenTelemetry.Instrumentation.GrpcNetClient
///
public class GrpcClientInstrumentationOptions
{
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GrpcClientInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal GrpcClientInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+
///
/// Gets or sets a value indicating whether down stream instrumentation is suppressed (disabled).
///
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs
index 04183129d15..73b7cd98f6f 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs
@@ -19,7 +19,6 @@
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Instrumentation.Http;
using OpenTelemetry.Trace;
-using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.GrpcNetClient.Implementation
{
@@ -37,14 +36,10 @@ internal sealed class GrpcClientDiagnosticListener : ListenerHandler
private readonly PropertyFetcher startRequestFetcher = new("Request");
private readonly PropertyFetcher stopRequestFetcher = new("Response");
- private readonly HttpSemanticConvention httpSemanticConvention;
-
public GrpcClientDiagnosticListener(GrpcClientInstrumentationOptions options)
: base("Grpc.Net.Client")
{
this.options = options;
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
}
public override void OnEventWritten(string name, object payload)
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj
index 11ef412972d..08c37511099 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj
@@ -13,7 +13,9 @@
-
+
+
+
diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs
index 00b5b55d505..504a242ac26 100644
--- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs
@@ -63,10 +63,15 @@ public static TracerProviderBuilder AddGrpcClientInstrumentation(
name ??= Options.DefaultName;
- if (configure != null)
+ builder.ConfigureServices(services =>
{
- builder.ConfigureServices(services => services.Configure(name, configure));
- }
+ if (configure != null)
+ {
+ services.Configure(name, configure);
+ }
+
+ services.RegisterOptionsFactory(configuration => new GrpcClientInstrumentationOptions(configuration));
+ });
builder.AddSource(GrpcClientDiagnosticListener.ActivitySourceName);
builder.AddLegacySource("Grpc.Net.Client.GrpcOut");
diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
index 1084bbdc44d..a4dd10a0639 100644
--- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs
@@ -20,7 +20,9 @@
using System.Net.Http;
#endif
using System.Runtime.CompilerServices;
+using Microsoft.Extensions.Configuration;
using OpenTelemetry.Instrumentation.Http.Implementation;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.Http
{
@@ -29,6 +31,23 @@ namespace OpenTelemetry.Instrumentation.Http
///
public class HttpClientInstrumentationOptions
{
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public HttpClientInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal HttpClientInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+
///
/// Gets or sets a filter function that determines whether or not to
/// collect telemetry on a per request basis.
diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetricInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetricInstrumentationOptions.cs
new file mode 100644
index 00000000000..57ce8b3a6b2
--- /dev/null
+++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetricInstrumentationOptions.cs
@@ -0,0 +1,42 @@
+//
+// 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 Microsoft.Extensions.Configuration;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
+
+namespace OpenTelemetry.Instrumentation.Http
+{
+ internal sealed class HttpClientMetricInstrumentationOptions
+ {
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public HttpClientMetricInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal HttpClientMetricInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+ }
+}
diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs
index 3bf57029d8a..8901643faf0 100644
--- a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs
@@ -44,10 +44,11 @@ internal sealed class HttpClientMetrics : IDisposable
///
/// Initializes a new instance of the class.
///
- public HttpClientMetrics()
+ /// HttpClient metric instrumentation options.
+ public HttpClientMetrics(HttpClientMetricInstrumentationOptions options)
{
this.meter = new Meter(InstrumentationName, InstrumentationVersion);
- this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerMetricsDiagnosticListener("HttpHandlerDiagnosticListener", this.meter), this.isEnabled);
+ this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerMetricsDiagnosticListener("HttpHandlerDiagnosticListener", this.meter, options), this.isEnabled);
this.diagnosticSourceSubscriber.Subscribe();
}
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
index 7197d772f1f..6248407b7a5 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs
@@ -46,8 +46,6 @@ internal sealed class HttpHandlerDiagnosticListener : ListenerHandler
private readonly PropertyFetcher stopRequestStatusFetcher = new("RequestTaskStatus");
private readonly HttpClientInstrumentationOptions options;
- private readonly HttpSemanticConvention httpSemanticConvention;
-
static HttpHandlerDiagnosticListener()
{
try
@@ -64,8 +62,6 @@ public HttpHandlerDiagnosticListener(HttpClientInstrumentationOptions options)
: base("HttpHandlerDiagnosticListener")
{
this.options = options;
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
}
public override void OnEventWritten(string name, object payload)
@@ -163,7 +159,7 @@ public void OnStartActivity(Activity activity, object payload)
}
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
activity.SetTag(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme);
activity.SetTag(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method));
@@ -178,7 +174,7 @@ public void OnStartActivity(Activity activity, object payload)
}
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
activity.SetTag(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme);
activity.SetTag(SemanticConventions.AttributeHttpRequestMethod, HttpTagHelper.GetNameForHttpMethod(request.Method));
@@ -242,12 +238,12 @@ public void OnStopActivity(Activity activity, object payload)
if (this.stopResponseFetcher.TryFetch(payload, out HttpResponseMessage response) && response != null)
{
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
activity.SetTag(SemanticConventions.AttributeHttpStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode));
}
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode));
}
diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
index 338a55dbf92..55d2e1edf74 100644
--- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
@@ -31,15 +31,13 @@ internal sealed class HttpHandlerMetricsDiagnosticListener : ListenerHandler
private readonly PropertyFetcher stopResponseFetcher = new("Response");
private readonly PropertyFetcher stopRequestFetcher = new("Request");
private readonly Histogram httpClientDuration;
+ private readonly HttpClientMetricInstrumentationOptions options;
- private readonly HttpSemanticConvention httpSemanticConvention;
-
- public HttpHandlerMetricsDiagnosticListener(string name, Meter meter)
+ public HttpHandlerMetricsDiagnosticListener(string name, Meter meter, HttpClientMetricInstrumentationOptions options)
: base(name)
{
this.httpClientDuration = meter.CreateHistogram("http.client.duration", "ms", "Measures the duration of outbound HTTP requests.");
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
+ this.options = options;
}
public override void OnEventWritten(string name, object payload)
@@ -57,7 +55,7 @@ public override void OnEventWritten(string name, object payload)
TagList tags = default;
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old))
{
tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)));
tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme));
@@ -76,7 +74,7 @@ public override void OnEventWritten(string name, object payload)
}
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/trace/semantic_conventions/http.md
- if (this.httpSemanticConvention.HasFlag(HttpSemanticConvention.New))
+ if (this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New))
{
tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)));
tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme));
diff --git a/src/OpenTelemetry.Instrumentation.Http/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/MeterProviderBuilderExtensions.cs
index b78c800dee7..0912cc6c967 100644
--- a/src/OpenTelemetry.Instrumentation.Http/MeterProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/MeterProviderBuilderExtensions.cs
@@ -14,6 +14,8 @@
// limitations under the License.
//
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
using OpenTelemetry.Instrumentation.Http;
using OpenTelemetry.Instrumentation.Http.Implementation;
using OpenTelemetry.Internal;
@@ -38,6 +40,11 @@ public static MeterProviderBuilder AddHttpClientInstrumentation(
// Note: Warm-up the status code mapping.
_ = TelemetryHelper.BoxedStatusCodes;
+ builder.ConfigureServices(services =>
+ {
+ services.RegisterOptionsFactory(configuration => new HttpClientMetricInstrumentationOptions(configuration));
+ });
+
// TODO: Implement an IDeferredMeterProviderBuilder
// TODO: Handle HttpClientInstrumentationOptions
@@ -46,9 +53,9 @@ public static MeterProviderBuilder AddHttpClientInstrumentation(
// Enrich - do we want a similar kind of functionality for metrics?
// RecordException - probably doesn't make sense for metric instrumentation
- var instrumentation = new HttpClientMetrics();
builder.AddMeter(HttpClientMetrics.InstrumentationName);
- return builder.AddInstrumentation(() => instrumentation);
+ return builder.AddInstrumentation(sp => new HttpClientMetrics(
+ sp.GetRequiredService>().CurrentValue));
}
}
}
diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj
index 23a8c183a25..21f527297a8 100644
--- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj
+++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj
@@ -13,7 +13,9 @@
-
+
+
+
diff --git a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs
index bebfd21eb9e..237a737a4c7 100644
--- a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs
+++ b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs
@@ -65,10 +65,15 @@ public static TracerProviderBuilder AddHttpClientInstrumentation(
name ??= Options.DefaultName;
- if (configureHttpClientInstrumentationOptions != null)
+ builder.ConfigureServices(services =>
{
- builder.ConfigureServices(services => services.Configure(name, configureHttpClientInstrumentationOptions));
- }
+ if (configureHttpClientInstrumentationOptions != null)
+ {
+ services.Configure(name, configureHttpClientInstrumentationOptions);
+ }
+
+ services.RegisterOptionsFactory(configuration => new HttpClientInstrumentationOptions(configuration));
+ });
#if NETFRAMEWORK
builder.AddSource(HttpWebRequestActivitySource.ActivitySourceName);
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
index fe17f8e907d..8849f218b72 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
@@ -17,7 +17,6 @@
using System.Data;
using System.Diagnostics;
using OpenTelemetry.Trace;
-using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.SqlClient.Implementation
{
@@ -41,14 +40,10 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler
private readonly PropertyFetcher exceptionFetcher = new("Exception");
private readonly SqlClientInstrumentationOptions options;
- private readonly HttpSemanticConvention httpSemanticConvention;
-
public SqlClientDiagnosticListener(string sourceName, SqlClientInstrumentationOptions options)
: base(sourceName)
{
this.options = options ?? new SqlClientInstrumentationOptions();
-
- this.httpSemanticConvention = GetSemanticConventionOptIn();
}
public override bool SupportsNullActivity => true;
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj
index 9a47a00608f..af7c4576c4e 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj
@@ -13,7 +13,9 @@
-
+
+
+
@@ -22,6 +24,7 @@
+
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs
index fdb0e29eff4..ed02895b391 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs
@@ -18,7 +18,9 @@
using System.Data;
using System.Diagnostics;
using System.Text.RegularExpressions;
+using Microsoft.Extensions.Configuration;
using OpenTelemetry.Trace;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
namespace OpenTelemetry.Instrumentation.SqlClient
{
@@ -30,6 +32,8 @@ namespace OpenTelemetry.Instrumentation.SqlClient
///
public class SqlClientInstrumentationOptions
{
+ internal readonly HttpSemanticConvention HttpSemanticConvention;
+
/*
* Match...
* protocol[ ]:[ ]serverName
@@ -63,6 +67,21 @@ public class SqlClientInstrumentationOptions
private static readonly ConcurrentDictionary ConnectionDetailCache = new(StringComparer.OrdinalIgnoreCase);
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SqlClientInstrumentationOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
+ {
+ }
+
+ internal SqlClientInstrumentationOptions(IConfiguration configuration)
+ {
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
+ }
+
///
/// Gets or sets a value indicating whether or not the should add the names of
{
- builder.ConfigureServices(services => services.Configure(name, configureSqlClientInstrumentationOptions));
- }
+ if (configureSqlClientInstrumentationOptions != null)
+ {
+ services.Configure(name, configureSqlClientInstrumentationOptions);
+ }
+
+ services.RegisterOptionsFactory(configuration => new SqlClientInstrumentationOptions(configuration));
+ });
builder.AddInstrumentation(sp =>
{
diff --git a/src/OpenTelemetry.Api/Internal/HttpSemanticConventionHelper.cs b/src/Shared/HttpSemanticConventionHelper.cs
similarity index 84%
rename from src/OpenTelemetry.Api/Internal/HttpSemanticConventionHelper.cs
rename to src/Shared/HttpSemanticConventionHelper.cs
index 1774cbd2069..61d002482c8 100644
--- a/src/OpenTelemetry.Api/Internal/HttpSemanticConventionHelper.cs
+++ b/src/Shared/HttpSemanticConventionHelper.cs
@@ -14,6 +14,11 @@
// limitations under the License.
//
+#nullable enable
+
+using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+
namespace OpenTelemetry.Internal;
///
@@ -27,8 +32,10 @@ namespace OpenTelemetry.Internal;
///
internal static class HttpSemanticConventionHelper
{
+ public const string SemanticConventionOptInKeyName = "OTEL_SEMCONV_STABILITY_OPT_IN";
+
[Flags]
- internal enum HttpSemanticConvention
+ public enum HttpSemanticConvention
{
///
/// Instructs an instrumentation library to emit the old experimental HTTP attributes.
@@ -46,11 +53,13 @@ internal enum HttpSemanticConvention
Dupe = Old | New,
}
- public static HttpSemanticConvention GetSemanticConventionOptIn()
+ public static HttpSemanticConvention GetSemanticConventionOptIn(IConfiguration configuration)
{
+ Debug.Assert(configuration != null, "configuration was null");
+
try
{
- var envVarValue = Environment.GetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN");
+ var envVarValue = configuration![SemanticConventionOptInKeyName];
return envVarValue?.ToLowerInvariant() switch
{
"http" => HttpSemanticConvention.New,
diff --git a/test/OpenTelemetry.Api.Tests/Internal/HttpSemanticConventionHelperTest.cs b/test/OpenTelemetry.Api.Tests/Internal/HttpSemanticConventionHelperTest.cs
deleted file mode 100644
index 48a92230ab7..00000000000
--- a/test/OpenTelemetry.Api.Tests/Internal/HttpSemanticConventionHelperTest.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// 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 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);
- }
- }
-}
diff --git a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj
index 4c67f8f2fe3..88c75b48306 100644
--- a/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj
+++ b/test/OpenTelemetry.Tests/OpenTelemetry.Tests.csproj
@@ -21,6 +21,7 @@
+
diff --git a/test/OpenTelemetry.Tests/Shared/HttpSemanticConventionHelperTest.cs b/test/OpenTelemetry.Tests/Shared/HttpSemanticConventionHelperTest.cs
new file mode 100644
index 00000000000..c68c0dc0c82
--- /dev/null
+++ b/test/OpenTelemetry.Tests/Shared/HttpSemanticConventionHelperTest.cs
@@ -0,0 +1,91 @@
+//
+// 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 Microsoft.Extensions.Configuration;
+using Xunit;
+using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
+
+namespace OpenTelemetry.Tests.Shared;
+
+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()
+ {
+ RunTestWithEnvironmentVariable(null, HttpSemanticConvention.Old);
+ RunTestWithEnvironmentVariable(string.Empty, HttpSemanticConvention.Old);
+ RunTestWithEnvironmentVariable("junk", HttpSemanticConvention.Old);
+ RunTestWithEnvironmentVariable("none", HttpSemanticConvention.Old);
+ RunTestWithEnvironmentVariable("NONE", HttpSemanticConvention.Old);
+ RunTestWithEnvironmentVariable("http", HttpSemanticConvention.New);
+ RunTestWithEnvironmentVariable("HTTP", HttpSemanticConvention.New);
+ RunTestWithEnvironmentVariable("http/dup", HttpSemanticConvention.Dupe);
+ RunTestWithEnvironmentVariable("HTTP/DUP", HttpSemanticConvention.Dupe);
+ }
+
+ [Fact]
+ public void VerifyGetSemanticConventionOptInUsingIConfiguration()
+ {
+ RunTestWithIConfiguration(null, HttpSemanticConvention.Old);
+ RunTestWithIConfiguration(string.Empty, HttpSemanticConvention.Old);
+ RunTestWithIConfiguration("junk", HttpSemanticConvention.Old);
+ RunTestWithIConfiguration("none", HttpSemanticConvention.Old);
+ RunTestWithIConfiguration("NONE", HttpSemanticConvention.Old);
+ RunTestWithIConfiguration("http", HttpSemanticConvention.New);
+ RunTestWithIConfiguration("HTTP", HttpSemanticConvention.New);
+ RunTestWithIConfiguration("http/dup", HttpSemanticConvention.Dupe);
+ RunTestWithIConfiguration("HTTP/DUP", HttpSemanticConvention.Dupe);
+ }
+
+ private static void RunTestWithEnvironmentVariable(string value, HttpSemanticConvention expected)
+ {
+ try
+ {
+ Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, value);
+
+ Assert.Equal(expected, GetSemanticConventionOptIn(new ConfigurationBuilder().AddEnvironmentVariables().Build()));
+ }
+ finally
+ {
+ Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, null);
+ }
+ }
+
+ private static void RunTestWithIConfiguration(string value, HttpSemanticConvention expected)
+ {
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = value })
+ .Build();
+
+ Assert.Equal(expected, GetSemanticConventionOptIn(configuration));
+ }
+}