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()
{