diff --git a/build/Common.props b/build/Common.props
index deed26cd9ca..e7a089f2b96 100644
--- a/build/Common.props
+++ b/build/Common.props
@@ -31,10 +31,11 @@
[2.1.1,6.0)
[3.3.3]
[17.3.0]
+ [3.1.0,)
[2.1.0,)
[3.1.0,)
[3.1.0,)
- [3.1.0,)
+ [5.0.0,)
[1.0.0,2.0)
[1.0.0,2.0)
[0.12.1,0.13)
diff --git a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
index 041b2df43eb..f60481649c0 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+* Added support for loading environment variables from `IConfiguration` when
+ using the `AddJaegerExporter` extension
+ ([#3720](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3720))
+
## 1.4.0-beta.1
Released 2022-Sep-29
diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
index c9da743562d..6a6bd83efc0 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs
@@ -62,10 +62,15 @@ public static TracerProviderBuilder AddJaegerExporter(
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 JaegerExporterOptions(configuration));
+ });
return builder.ConfigureBuilder((sp, builder) =>
{
diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
index b992048d338..f2946388b90 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs
@@ -17,6 +17,7 @@
using System;
using System.Diagnostics;
using System.Net.Http;
+using Microsoft.Extensions.Configuration;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
@@ -43,37 +44,45 @@ public class JaegerExporterOptions
internal static readonly Func DefaultHttpClientFactory = () => new HttpClient();
+ ///
+ /// Initializes a new instance of the class.
+ ///
public JaegerExporterOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
{
- if (EnvironmentVariableHelper.LoadString(OTelProtocolEnvVarKey, out string protocolEnvVar))
+ }
+
+ internal JaegerExporterOptions(IConfiguration configuration)
+ {
+ if (configuration.TryGetValue(
+ OTelProtocolEnvVarKey,
+ JaegerExporterProtocolParser.TryParse,
+ out var protocol))
{
- if (JaegerExporterProtocolParser.TryParse(protocolEnvVar, out var protocol))
- {
- this.Protocol = protocol;
- }
- else
- {
- throw new FormatException($"{OTelProtocolEnvVarKey} environment variable has an invalid value: '{protocolEnvVar}'");
- }
+ this.Protocol = protocol;
}
- if (EnvironmentVariableHelper.LoadString(OTelAgentHostEnvVarKey, out string agentHostEnvVar))
+ if (configuration.TryGetStringValue(OTelAgentHostEnvVarKey, out var agentHost))
{
- this.AgentHost = agentHostEnvVar;
+ this.AgentHost = agentHost;
}
- if (EnvironmentVariableHelper.LoadNumeric(OTelAgentPortEnvVarKey, out int agentPortEnvVar))
+ if (configuration.TryGetIntValue(OTelAgentPortEnvVarKey, out var agentPort))
{
- this.AgentPort = agentPortEnvVar;
+ this.AgentPort = agentPort;
}
- if (EnvironmentVariableHelper.LoadString(OTelEndpointEnvVarKey, out string endpointEnvVar)
- && Uri.TryCreate(endpointEnvVar, UriKind.Absolute, out Uri endpoint))
+ if (configuration.TryGetUriValue(OTelEndpointEnvVarKey, out var endpoint))
{
this.Endpoint = endpoint;
}
}
+ ///
+ /// Gets or sets the to use when
+ /// communicating to Jaeger. Default value: .
+ ///
public JaegerExportProtocol Protocol { get; set; } = JaegerExportProtocol.UdpCompactThrift;
///
diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterProtocolParser.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterProtocolParser.cs
index 52fb109350f..2a770135541 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterProtocolParser.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterProtocolParser.cs
@@ -20,7 +20,7 @@ internal static class JaegerExporterProtocolParser
{
public static bool TryParse(string value, out JaegerExportProtocol result)
{
- switch (value?.Trim())
+ switch (value.Trim().ToLower())
{
case "udp/thrift.compact":
result = JaegerExportProtocol.UdpCompactThrift;
diff --git a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj
index abd411f0df3..2720fd1a2b2 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj
+++ b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
index 352288c42a8..eb922b12f2b 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+* Added support for loading environment variables from `IConfiguration` when
+ using the `AddZipkinExporter` extension
+ ([#3759](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3759))
+
## 1.4.0-beta.1
Released 2022-Sep-29
diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj
index 0aee4bd6334..c5e14a100de 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj
+++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
index 261cecd1a64..93a43014874 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs
@@ -62,10 +62,15 @@ public static TracerProviderBuilder AddZipkinExporter(
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 ZipkinExporterOptions(configuration));
+ });
return builder.ConfigureBuilder((sp, builder) =>
{
diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
index 9c354574a72..d51eb007b81 100644
--- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterOptions.cs
@@ -17,6 +17,7 @@
using System;
using System.Diagnostics;
using System.Net.Http;
+using Microsoft.Extensions.Configuration;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;
@@ -44,8 +45,13 @@ public sealed class ZipkinExporterOptions
/// Initializes zipkin endpoint.
///
public ZipkinExporterOptions()
+ : this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
{
- if (EnvironmentVariableHelper.LoadUri(ZipkinEndpointEnvVar, out Uri endpoint))
+ }
+
+ internal ZipkinExporterOptions(IConfiguration configuration)
+ {
+ if (configuration.TryGetUriValue(ZipkinEndpointEnvVar, out var endpoint))
{
this.Endpoint = endpoint;
}
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md
index 23af195b8d5..9fca6a77d4e 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md
@@ -2,6 +2,12 @@
## Unreleased
+* Use `Activity.Status` and `Activity.StatusDescription` properties instead of
+ `OpenTelemetry.Trace.Status` and `OpenTelemetry.Trace.Status.Description`
+ respectively to set activity status.
+ ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118))
+ ([#3751](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3751))
+
## 1.0.0-rc9.7
Released 2022-Sep-29
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
index 4f360bcbf18..aa6f2ccc4e3 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs
@@ -146,17 +146,7 @@ public override void OnEventWritten(string name, object payload)
return;
}
- try
- {
- if (activity.IsAllDataRequested)
- {
- activity.SetStatus(Status.Unset);
- }
- }
- finally
- {
- activity.Stop();
- }
+ activity.Stop();
}
break;
@@ -180,7 +170,7 @@ public override void OnEventWritten(string name, object payload)
{
if (this.exceptionFetcher.TryFetch(payload, out Exception exception) && exception != null)
{
- activity.SetStatus(Status.Error.WithDescription(exception.Message));
+ activity.SetStatus(ActivityStatusCode.Error, exception.Message);
if (this.options.RecordException)
{
diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs
index 9417df4798d..fde30c97575 100644
--- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs
+++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs
@@ -181,18 +181,17 @@ private void OnEndExecute(EventWrittenEventArgs eventData)
if (activity.IsAllDataRequested)
{
int compositeState = (int)eventData.Payload[1];
- if ((compositeState & 0b001) == 0b001)
+ if ((compositeState & 0b001) != 0b001)
{
- activity.SetStatus(Status.Unset);
- }
- else if ((compositeState & 0b010) == 0b010)
- {
- var errorText = $"SqlExceptionNumber {eventData.Payload[2]} thrown.";
- activity.SetStatus(Status.Error.WithDescription(errorText));
- }
- else
- {
- activity.SetStatus(Status.Error.WithDescription("Unknown Sql failure."));
+ if ((compositeState & 0b010) == 0b010)
+ {
+ var errorText = $"SqlExceptionNumber {eventData.Payload[2]} thrown.";
+ activity.SetStatus(ActivityStatusCode.Error, errorText);
+ }
+ else
+ {
+ activity.SetStatus(ActivityStatusCode.Error, "Unknown Sql failure.");
+ }
}
}
}
diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md
index a189a19f0c5..5ea2486a319 100644
--- a/src/OpenTelemetry/CHANGELOG.md
+++ b/src/OpenTelemetry/CHANGELOG.md
@@ -12,6 +12,10 @@
`BatchLogRecordExportProcessor.OnEnd` is fired.
([#3731](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3731))
+* Added support for loading environment variables from `IConfiguration` when
+ using `TracerProviderBuilder` or `MeterProviderBuilder`
+ ([#3720](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3720))
+
## 1.4.0-beta.1
Released 2022-Sep-29
diff --git a/src/OpenTelemetry/Internal/Builder/ProviderBuilderServiceCollectionExtensions.cs b/src/OpenTelemetry/Internal/Builder/ProviderBuilderServiceCollectionExtensions.cs
new file mode 100644
index 00000000000..ab136d3a4f0
--- /dev/null
+++ b/src/OpenTelemetry/Internal/Builder/ProviderBuilderServiceCollectionExtensions.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.
+//
+
+#nullable enable
+
+using System.Diagnostics;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Microsoft.Extensions.DependencyInjection;
+
+internal static class ProviderBuilderServiceCollectionExtensions
+{
+ public static IServiceCollection AddOpenTelemetryProviderBuilderServices(this IServiceCollection services)
+ {
+ Debug.Assert(services != null, "services was null");
+
+ services.AddOptions();
+
+ // Note: When using a host builder IConfiguration is automatically
+ // registered and this registration will no-op. This only runs for
+ // Sdk.Create* style or when manually creating a ServiceCollection. The
+ // point of this registration is to make IConfiguration available in
+ // those cases.
+ services!.TryAddSingleton(sp => new ConfigurationBuilder().AddEnvironmentVariables().Build());
+
+ return services!;
+ }
+}
diff --git a/src/OpenTelemetry/Internal/ConfigurationExtensions.cs b/src/OpenTelemetry/Internal/ConfigurationExtensions.cs
new file mode 100644
index 00000000000..dc22bbf673c
--- /dev/null
+++ b/src/OpenTelemetry/Internal/ConfigurationExtensions.cs
@@ -0,0 +1,164 @@
+//
+// 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.
+//
+
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+using System.Diagnostics.CodeAnalysis;
+#endif
+using System.Globalization;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+
+namespace OpenTelemetry.Internal;
+
+internal static class ConfigurationExtensions
+{
+ public delegate bool TryParseFunc(
+ string value,
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+ [NotNullWhen(true)]
+#endif
+ out T? parsedValue);
+
+ public static bool TryGetStringValue(
+ this IConfiguration configuration,
+ string key,
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+ [NotNullWhen(true)]
+#endif
+ out string? value)
+ {
+ value = configuration.GetValue(key, null);
+
+ return !string.IsNullOrWhiteSpace(value);
+ }
+
+ public static bool TryGetUriValue(
+ this IConfiguration configuration,
+ string key,
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+ [NotNullWhen(true)]
+#endif
+ out Uri? value)
+ {
+ if (!configuration.TryGetStringValue(key, out var stringValue))
+ {
+ value = null;
+ return false;
+ }
+
+ if (!Uri.TryCreate(stringValue, UriKind.Absolute, out value))
+ {
+ throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'");
+ }
+
+ return true;
+ }
+
+ public static bool TryGetIntValue(
+ this IConfiguration configuration,
+ string key,
+ out int value)
+ {
+ if (!configuration.TryGetStringValue(key, out var stringValue))
+ {
+ value = default;
+ return false;
+ }
+
+ if (!int.TryParse(stringValue, NumberStyles.None, CultureInfo.InvariantCulture, out value))
+ {
+ throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'");
+ }
+
+ return true;
+ }
+
+ public static bool TryGetValue(
+ this IConfiguration configuration,
+ string key,
+ TryParseFunc tryParseFunc,
+#if !NETFRAMEWORK && !NETSTANDARD2_0
+ [NotNullWhen(true)]
+#endif
+ out T? value)
+ {
+ if (!configuration.TryGetStringValue(key, out var stringValue))
+ {
+ value = default;
+ return false;
+ }
+
+ if (!tryParseFunc(stringValue!, out value))
+ {
+ throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'");
+ }
+
+ return true;
+ }
+
+ public static IServiceCollection RegisterOptionsFactory(
+ this IServiceCollection services,
+ Func optionsFactoryFunc)
+ where T : class
+ {
+ Debug.Assert(services != null, "services was null");
+ Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null");
+
+ services!.TryAddSingleton>(sp =>
+ {
+ return new DelegatingOptionsFactory(
+ optionsFactoryFunc!,
+ sp.GetRequiredService(),
+ sp.GetServices>(),
+ sp.GetServices>(),
+ sp.GetServices>());
+ });
+
+ return services!;
+ }
+
+ private sealed class DelegatingOptionsFactory : OptionsFactory
+ where T : class
+ {
+ private readonly Func optionsFactoryFunc;
+ private readonly IConfiguration configuration;
+
+ public DelegatingOptionsFactory(
+ Func optionsFactoryFunc,
+ IConfiguration configuration,
+ IEnumerable> setups,
+ IEnumerable> postConfigures,
+ IEnumerable> validations)
+ : base(setups, postConfigures, validations)
+ {
+ Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null");
+ Debug.Assert(configuration != null, "configuration was null");
+
+ this.optionsFactoryFunc = optionsFactoryFunc!;
+ this.configuration = configuration!;
+ }
+
+ protected override T CreateInstance(string name)
+ => this.optionsFactoryFunc(this.configuration);
+ }
+}
diff --git a/src/OpenTelemetry/Internal/EnvironmentVariableHelper.cs b/src/OpenTelemetry/Internal/EnvironmentVariableHelper.cs
index f6ea9783590..6a745e4ad11 100644
--- a/src/OpenTelemetry/Internal/EnvironmentVariableHelper.cs
+++ b/src/OpenTelemetry/Internal/EnvironmentVariableHelper.cs
@@ -76,6 +76,25 @@ public static bool LoadNumeric(string envVarKey, out int result)
return false;
}
+ return LoadNumeric(envVarKey, value, out result);
+ }
+
+ ///
+ /// Reads an environment variable and parses is as a
+ ///
+ /// numeric value - a non-negative decimal integer.
+ ///
+ /// The name of the environment variable.
+ /// The value of the environment variable.
+ /// The parsed value of the environment variable.
+ ///
+ /// Returns true when a non-empty value was read; otherwise, false.
+ ///
+ ///
+ /// Thrown when failed to parse the non-empty value.
+ ///
+ public static bool LoadNumeric(string envVarKey, string value, out int result)
+ {
if (!int.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result))
{
throw new FormatException($"{envVarKey} environment variable has an invalid value: '{value}'");
diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs
index 186926a5799..80482d7b5cd 100644
--- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs
+++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs
@@ -52,7 +52,7 @@ internal MeterProviderBuilderBase(IServiceCollection services)
{
Guard.ThrowIfNull(services);
- services.AddOptions();
+ services.AddOpenTelemetryProviderBuilderServices();
services.TryAddSingleton(sp => new MeterProviderSdk(sp, ownsServiceProvider: false));
this.services = services;
@@ -65,7 +65,7 @@ protected MeterProviderBuilderBase()
{
var services = new ServiceCollection();
- services.AddOptions();
+ services.AddOpenTelemetryProviderBuilderServices();
this.services = services;
this.ownsServices = true;
diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs
index e53f412828d..779e7f017f6 100644
--- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs
+++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs
@@ -42,7 +42,7 @@ internal static IServiceCollection RegisterConfigureStateCallback(
Debug.Assert(services != null, "services was null");
Debug.Assert(configure != null, "configure was null");
- return services.AddSingleton(new ConfigureMeterProviderBuilderStateCallbackRegistration(configure!));
+ return services!.AddSingleton(new ConfigureMeterProviderBuilderStateCallbackRegistration(configure!));
}
internal static void InvokeRegisteredConfigureStateCallbacks(
@@ -52,7 +52,7 @@ internal static void InvokeRegisteredConfigureStateCallbacks(
Debug.Assert(serviceProvider != null, "serviceProvider was null");
Debug.Assert(state != null, "state was null");
- var callbackRegistrations = serviceProvider.GetServices();
+ var callbackRegistrations = serviceProvider!.GetServices();
foreach (var callbackRegistration in callbackRegistrations)
{
diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj
index 542fcc9e407..c05c686b45b 100644
--- a/src/OpenTelemetry/OpenTelemetry.csproj
+++ b/src/OpenTelemetry/OpenTelemetry.csproj
@@ -17,8 +17,10 @@
+
+
diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
index a747395308c..223f07e798c 100644
--- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
+++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
@@ -51,7 +51,7 @@ internal TracerProviderBuilderBase(IServiceCollection services)
{
Guard.ThrowIfNull(services);
- services.AddOptions();
+ services.AddOpenTelemetryProviderBuilderServices();
services.TryAddSingleton(sp => new TracerProviderSdk(sp, ownsServiceProvider: false));
this.services = services;
@@ -64,7 +64,7 @@ protected TracerProviderBuilderBase()
{
var services = new ServiceCollection();
- services.AddOptions();
+ services.AddOpenTelemetryProviderBuilderServices();
this.services = services;
this.ownsServices = true;
diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderServiceCollectionHelper.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderServiceCollectionHelper.cs
index ae68e0881b5..5de52f1a495 100644
--- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderServiceCollectionHelper.cs
+++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderServiceCollectionHelper.cs
@@ -42,7 +42,7 @@ internal static IServiceCollection RegisterConfigureStateCallback(
Debug.Assert(services != null, "services was null");
Debug.Assert(configure != null, "configure was null");
- return services.AddSingleton(new ConfigureTracerProviderBuilderStateCallbackRegistration(configure!));
+ return services!.AddSingleton(new ConfigureTracerProviderBuilderStateCallbackRegistration(configure!));
}
internal static void InvokeRegisteredConfigureStateCallbacks(
@@ -52,7 +52,7 @@ internal static void InvokeRegisteredConfigureStateCallbacks(
Debug.Assert(serviceProvider != null, "serviceProvider was null");
Debug.Assert(state != null, "state was null");
- var callbackRegistrations = serviceProvider.GetServices();
+ var callbackRegistrations = serviceProvider!.GetServices();
foreach (var callbackRegistration in callbackRegistrations)
{
diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs
index 33143faf16f..42b0548be66 100644
--- a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs
+++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs
@@ -15,6 +15,8 @@
//
using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.Configuration;
using Xunit;
namespace OpenTelemetry.Exporter.Jaeger.Tests
@@ -93,6 +95,29 @@ public void JaegerExporterOptions_EnvironmentVariableNames()
Assert.Equal("OTEL_EXPORTER_JAEGER_ENDPOINT", JaegerExporterOptions.OTelEndpointEnvVarKey);
}
+ [Fact]
+ public void JaegerExporterOptions_FromConfigurationTest()
+ {
+ var values = new Dictionary()
+ {
+ [JaegerExporterOptions.OTelProtocolEnvVarKey] = "http/thrift.binary",
+ [JaegerExporterOptions.OTelAgentHostEnvVarKey] = "jaeger-host",
+ [JaegerExporterOptions.OTelAgentPortEnvVarKey] = "123",
+ [JaegerExporterOptions.OTelEndpointEnvVarKey] = "http://custom-endpoint:12345",
+ };
+
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(values)
+ .Build();
+
+ var options = new JaegerExporterOptions(configuration);
+
+ Assert.Equal("jaeger-host", options.AgentHost);
+ Assert.Equal(123, options.AgentPort);
+ Assert.Equal(JaegerExportProtocol.HttpBinaryThrift, options.Protocol);
+ Assert.Equal(new Uri("http://custom-endpoint:12345"), options.Endpoint);
+ }
+
private static void ClearEnvVars()
{
Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelProtocolEnvVarKey, null);
diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs
index 4cd2d97d2e5..3c19c2c106c 100644
--- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs
+++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs
@@ -23,6 +23,7 @@
using System.Net;
using System.Net.Http;
using System.Text;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter.Zipkin.Implementation;
using OpenTelemetry.Resources;
@@ -207,6 +208,23 @@ public void ErrorGettingUriFromEnvVarSetsDefaultEndpointValue()
}
}
+ [Fact]
+ public void EndpointConfigurationUsingIConfiguration()
+ {
+ var values = new Dictionary()
+ {
+ [ZipkinExporterOptions.ZipkinEndpointEnvVar] = "http://custom-endpoint:12345",
+ };
+
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(values)
+ .Build();
+
+ var options = new ZipkinExporterOptions(configuration);
+
+ Assert.Equal(new Uri("http://custom-endpoint:12345"), options.Endpoint);
+ }
+
[Fact]
public void UserHttpFactoryCalled()
{
diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs
index f4acf44b4e2..4553ae33926 100644
--- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs
+++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs
@@ -15,13 +15,14 @@
//
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry.Metrics;
using Xunit;
-using static OpenTelemetry.Extensions.Hosting.Tests.HostingTracerExtensionTests;
namespace OpenTelemetry.Extensions.Hosting.Tests
{
@@ -195,6 +196,49 @@ public void AddOpenTelemetryMetrics_MultipleCallsConfigureSingleProvider()
Assert.Single(providers);
}
+ [Fact]
+ public async Task AddOpenTelemetryMetrics_HostConfigurationHonoredTest()
+ {
+ bool configureBuilderCalled = false;
+
+ var builder = new HostBuilder()
+ .ConfigureAppConfiguration(builder =>
+ {
+ builder.AddInMemoryCollection(new Dictionary
+ {
+ ["TEST_KEY"] = "TEST_KEY_VALUE",
+ });
+ })
+ .ConfigureServices(services =>
+ {
+ services.AddOpenTelemetryMetrics(builder =>
+ {
+ builder.ConfigureBuilder((sp, builder) =>
+ {
+ configureBuilderCalled = true;
+
+ var configuration = sp.GetRequiredService();
+
+ var testKeyValue = configuration.GetValue("TEST_KEY", null);
+
+ Assert.Equal("TEST_KEY_VALUE", testKeyValue);
+ });
+ });
+ });
+
+ var host = builder.Build();
+
+ Assert.False(configureBuilderCalled);
+
+ await host.StartAsync();
+
+ Assert.True(configureBuilderCalled);
+
+ await host.StopAsync();
+
+ host.Dispose();
+ }
+
private static MeterProviderBuilder AddMyFeature(MeterProviderBuilder meterProviderBuilder)
{
meterProviderBuilder.ConfigureServices(services => services.AddSingleton());
diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingTracerExtensionTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingTracerExtensionTests.cs
index 131e9038139..22432e3f4a7 100644
--- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingTracerExtensionTests.cs
+++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingTracerExtensionTests.cs
@@ -15,9 +15,11 @@
//
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry.Trace;
@@ -198,6 +200,49 @@ public void AddOpenTelemetryTracing_MultipleCallsConfigureSingleProvider()
Assert.Single(providers);
}
+ [Fact]
+ public async Task AddOpenTelemetryTracing_HostConfigurationHonoredTest()
+ {
+ bool configureBuilderCalled = false;
+
+ var builder = new HostBuilder()
+ .ConfigureAppConfiguration(builder =>
+ {
+ builder.AddInMemoryCollection(new Dictionary
+ {
+ ["TEST_KEY"] = "TEST_KEY_VALUE",
+ });
+ })
+ .ConfigureServices(services =>
+ {
+ services.AddOpenTelemetryTracing(builder =>
+ {
+ builder.ConfigureBuilder((sp, builder) =>
+ {
+ configureBuilderCalled = true;
+
+ var configuration = sp.GetRequiredService();
+
+ var testKeyValue = configuration.GetValue("TEST_KEY", null);
+
+ Assert.Equal("TEST_KEY_VALUE", testKeyValue);
+ });
+ });
+ });
+
+ var host = builder.Build();
+
+ Assert.False(configureBuilderCalled);
+
+ await host.StartAsync();
+
+ Assert.True(configureBuilderCalled);
+
+ await host.StopAsync();
+
+ host.Dispose();
+ }
+
private static TracerProviderBuilder AddMyFeature(TracerProviderBuilder tracerProviderBuilder)
{
tracerProviderBuilder.ConfigureServices(services => services.AddSingleton());
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
index 6c1979d0d58..68cc737246d 100644
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
+++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
@@ -326,13 +326,13 @@ private static void VerifyActivityData(
if (!isFailure)
{
- Assert.Equal(Status.Unset, activity.GetStatus());
+ Assert.Equal(ActivityStatusCode.Unset, activity.Status);
}
else
{
var status = activity.GetStatus();
- Assert.Equal(Status.Error.StatusCode, status.StatusCode);
- Assert.NotNull(status.Description);
+ Assert.Equal(ActivityStatusCode.Error, activity.Status);
+ Assert.NotNull(activity.StatusDescription);
if (recordException)
{
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs
index 66c3264cf6c..0db32cfdd4e 100644
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs
+++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs
@@ -276,13 +276,12 @@ private static void VerifyActivityData(
if (!isFailure)
{
- Assert.Equal(Status.Unset, activity.GetStatus());
+ Assert.Equal(ActivityStatusCode.Unset, activity.Status);
}
else
{
- var status = activity.GetStatus();
- Assert.Equal(Status.Error.StatusCode, status.StatusCode);
- Assert.NotNull(status.Description);
+ Assert.Equal(ActivityStatusCode.Error, activity.Status);
+ Assert.NotNull(activity.StatusDescription);
}
}
diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs
index b4c96f2cc7c..7691f22f349 100644
--- a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs
+++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs
@@ -17,6 +17,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using OpenTelemetry.Resources;
@@ -199,6 +200,60 @@ public void SetAndConfigureResourceTest()
Assert.Contains(provider.Resource.Attributes, kvp => kvp.Key == "key2" && (string)kvp.Value == "value2");
}
+ [Fact]
+ public void ConfigureBuilderIConfigurationAvailableTest()
+ {
+ Environment.SetEnvironmentVariable("TEST_KEY", "TEST_KEY_VALUE");
+
+ bool configureBuilderCalled = false;
+
+ using var provider = Sdk.CreateMeterProviderBuilder()
+ .ConfigureBuilder((sp, builder) =>
+ {
+ var configuration = sp.GetRequiredService();
+
+ configureBuilderCalled = true;
+
+ var testKeyValue = configuration.GetValue("TEST_KEY", null);
+
+ Assert.Equal("TEST_KEY_VALUE", testKeyValue);
+ })
+ .Build();
+
+ Assert.True(configureBuilderCalled);
+
+ Environment.SetEnvironmentVariable("TEST_KEY", null);
+ }
+
+ [Fact]
+ public void ConfigureBuilderIConfigurationModifiableTest()
+ {
+ bool configureBuilderCalled = false;
+
+ using var provider = Sdk.CreateMeterProviderBuilder()
+ .ConfigureServices(services =>
+ {
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" })
+ .Build();
+
+ services.AddSingleton(configuration);
+ })
+ .ConfigureBuilder((sp, builder) =>
+ {
+ var configuration = sp.GetRequiredService();
+
+ configureBuilderCalled = true;
+
+ var testKey2Value = configuration.GetValue("TEST_KEY_2", null);
+
+ Assert.Equal("TEST_KEY_2_VALUE", testKey2Value);
+ })
+ .Build();
+
+ Assert.True(configureBuilderCalled);
+ }
+
private static void RunBuilderServiceLifecycleTest(
MeterProviderBuilder builder,
Func buildFunc,
diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs
index 383e691d358..34cc5a8e3ec 100644
--- a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs
+++ b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs
@@ -18,6 +18,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using OpenTelemetry.Resources;
@@ -393,6 +394,60 @@ public void AddExporterNamedOptionsTest()
Assert.Equal(1, namedOptionsConfigureInvocations);
}
+ [Fact]
+ public void ConfigureBuilderIConfigurationAvailableTest()
+ {
+ Environment.SetEnvironmentVariable("TEST_KEY", "TEST_KEY_VALUE");
+
+ bool configureBuilderCalled = false;
+
+ using var provider = Sdk.CreateTracerProviderBuilder()
+ .ConfigureBuilder((sp, builder) =>
+ {
+ var configuration = sp.GetRequiredService();
+
+ configureBuilderCalled = true;
+
+ var testKeyValue = configuration.GetValue("TEST_KEY", null);
+
+ Assert.Equal("TEST_KEY_VALUE", testKeyValue);
+ })
+ .Build();
+
+ Assert.True(configureBuilderCalled);
+
+ Environment.SetEnvironmentVariable("TEST_KEY", null);
+ }
+
+ [Fact]
+ public void ConfigureBuilderIConfigurationModifiableTest()
+ {
+ bool configureBuilderCalled = false;
+
+ using var provider = Sdk.CreateTracerProviderBuilder()
+ .ConfigureServices(services =>
+ {
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary { ["TEST_KEY_2"] = "TEST_KEY_2_VALUE" })
+ .Build();
+
+ services.AddSingleton(configuration);
+ })
+ .ConfigureBuilder((sp, builder) =>
+ {
+ var configuration = sp.GetRequiredService();
+
+ configureBuilderCalled = true;
+
+ var testKey2Value = configuration.GetValue("TEST_KEY_2", null);
+
+ Assert.Equal("TEST_KEY_2_VALUE", testKey2Value);
+ })
+ .Build();
+
+ Assert.True(configureBuilderCalled);
+ }
+
private static void RunBuilderServiceLifecycleTest(
TracerProviderBuilder builder,
Func buildFunc,