diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 79d6d1f3b10..2a9fdf13c4e 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -7,6 +7,12 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Fixed an issue where `OtlpExporterOptions` did not read environment variables (e.g. `OTEL_EXPORTER_OTLP_ENDPOINT`) + if the environment variables were set after `IConfiguration` was built. + ([#6558](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6558)) + This change also addresses similar issues when .Net `Host` does not load environment variables into `IConfiguration` (e.g. `Host.CreateEmptyApplicationBuilder`). + ([#5586](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5586)) + ## 1.13.0 Released 2025-Oct-01 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 91ebfdbd3e1..4ffaca35b69 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -48,27 +48,33 @@ public class OtlpExporterOptions : IOtlpExporterOptions /// Initializes a new instance of the class. /// public OtlpExporterOptions() - : this(OtlpExporterOptionsConfigurationType.Default) + : this(configurationType: OtlpExporterOptionsConfigurationType.Default) { } - internal OtlpExporterOptions( - OtlpExporterOptionsConfigurationType configurationType) + internal OtlpExporterOptions(OtlpExporterOptionsConfigurationType configurationType) : this( - configuration: new ConfigurationBuilder().AddEnvironmentVariables().Build(), - configurationType, - defaultBatchOptions: new()) + configuration: null, + configurationType: configurationType, + defaultBatchOptions: new()) { } internal OtlpExporterOptions( - IConfiguration configuration, + IConfiguration? configuration, OtlpExporterOptionsConfigurationType configurationType, BatchExportActivityProcessorOptions defaultBatchOptions) { Debug.Assert(defaultBatchOptions != null, "defaultBatchOptions was null"); + var finalConfigurationBuilder = new ConfigurationBuilder() + .AddEnvironmentVariables(); + + if (configuration != null) + { + finalConfigurationBuilder = finalConfigurationBuilder.AddConfiguration(configuration); + } - this.ApplyConfiguration(configuration, configurationType); + this.ApplyConfiguration(finalConfigurationBuilder.Build(), configurationType); this.DefaultHttpClientFactory = () => { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs index 9536d283cf5..77b2d2f0020 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs @@ -2,6 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using OpenTelemetry.Trace; using Xunit; namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; @@ -164,6 +168,44 @@ public void OtlpExporterOptions_SetterOverridesEnvironmentVariable() Assert.False(options.AppendSignalPathToEndpoint); } + // https://github.com/open-telemetry/opentelemetry-dotnet/issues/6558 + [Fact] + public void OtlpExporterOptions_EnvironmentVariableAppliedAfterIConfigurationBuilt() + { + var expectedEndpoint = "http://test:4317"; + var host = Host + .CreateDefaultBuilder() + .ConfigureServices((_, services) => + { + Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", expectedEndpoint); + services + .AddOpenTelemetry() + .WithTracing(builder => builder.AddOtlpExporter()); + }) + .Build(); + + var options = host.Services.GetRequiredService>().Value; + + Assert.Equal(new Uri(expectedEndpoint), options.Endpoint); + } + + // https://github.com/open-telemetry/opentelemetry-dotnet/issues/5586 + [Fact] + public void OtlpExporterOptions_EnvironmentVariableAppliedWhenEmptyApplication() + { + var expectedEndpoint = "http://test:4317"; + Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT", expectedEndpoint); + var hostBuilder = Host.CreateEmptyApplicationBuilder(settings: null); + hostBuilder.Services + .AddOpenTelemetry() + .WithTracing(builder => builder.AddOtlpExporter()); + var host = hostBuilder.Build(); + + var options = host.Services.GetRequiredService>().Value; + + Assert.Equal(new Uri(expectedEndpoint), options.Endpoint); + } + [Fact] public void OtlpExporterOptions_EndpointGetterUsesProtocolWhenNull() {