diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterOptionsConfigurationType.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterOptionsConfigurationType.cs new file mode 100644 index 00000000000..d3cedd6915c --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterOptionsConfigurationType.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +namespace OpenTelemetry.Exporter; + +[Flags] +internal enum OtlpExporterOptionsConfigurationType +{ +#pragma warning disable SA1602 // Enumeration items should be documented + Default, + Logs, + Metrics, + Traces, +#pragma warning restore SA1602 // Enumeration items should be documented +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterSpecEnvVarKeyDefinitions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterSpecEnvVarKeyDefinitions.cs deleted file mode 100644 index c7e4dad9181..00000000000 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpExporterSpecEnvVarKeyDefinitions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Exporter; - -/// -/// Contains spec environment variable key definitions for OpenTelemetry Protocol (OTLP) exporter. -/// -/// -/// Specification: . -/// -internal static class OtlpExporterSpecEnvVarKeyDefinitions -{ - public const string DefaultEndpointEnvVarName = "OTEL_EXPORTER_OTLP_ENDPOINT"; - public const string DefaultHeadersEnvVarName = "OTEL_EXPORTER_OTLP_HEADERS"; - public const string DefaultTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TIMEOUT"; - public const string DefaultProtocolEnvVarName = "OTEL_EXPORTER_OTLP_PROTOCOL"; - - public const string MetricsTemporalityPreferenceEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"; -} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpSpecConfigDefinitions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpSpecConfigDefinitions.cs new file mode 100644 index 00000000000..3bc62218b3f --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpSpecConfigDefinitions.cs @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Exporter; + +/// +/// Contains spec environment variable key definitions for OpenTelemetry Protocol (OTLP) exporter. +/// +/// +/// Specification: . +/// +internal static class OtlpSpecConfigDefinitions +{ + public const string DefaultEndpointEnvVarName = "OTEL_EXPORTER_OTLP_ENDPOINT"; + public const string DefaultHeadersEnvVarName = "OTEL_EXPORTER_OTLP_HEADERS"; + public const string DefaultTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TIMEOUT"; + public const string DefaultProtocolEnvVarName = "OTEL_EXPORTER_OTLP_PROTOCOL"; + + public const string LogsEndpointEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"; + public const string LogsHeadersEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_HEADERS"; + public const string LogsTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT"; + public const string LogsProtocolEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL"; + + public const string MetricsEndpointEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"; + public const string MetricsHeadersEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_HEADERS"; + public const string MetricsTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT"; + public const string MetricsProtocolEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL"; + public const string MetricsTemporalityPreferenceEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"; + + public const string TracesEndpointEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"; + public const string TracesHeadersEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_HEADERS"; + public const string TracesTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT"; + public const string TracesProtocolEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"; +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 05382efd6ce..0cffd50806c 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -17,11 +17,18 @@ namespace OpenTelemetry.Exporter; /// /// OpenTelemetry Protocol (OTLP) exporter options. -/// OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_PROTOCOL -/// environment variables are parsed during object construction. /// +/// +/// Note: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, +/// OTEL_EXPORTER_OTLP_TIMEOUT, and OTEL_EXPORTER_OTLP_PROTOCOL environment +/// variables are parsed during object construction. +/// public class OtlpExporterOptions { + internal const string DefaultGrpcEndpoint = "http://localhost:4317"; + internal const string DefaultHttpEndpoint = "http://localhost:4318"; + internal const OtlpExportProtocol DefaultOtlpExportProtocol = OtlpExportProtocol.Grpc; + internal static readonly KeyValuePair[] StandardHeaders = new KeyValuePair[] { new KeyValuePair("User-Agent", GetUserAgentString()), @@ -29,9 +36,6 @@ public class OtlpExporterOptions internal readonly Func DefaultHttpClientFactory; - private const string DefaultGrpcEndpoint = "http://localhost:4317"; - private const string DefaultHttpEndpoint = "http://localhost:4318"; - private const OtlpExportProtocol DefaultOtlpExportProtocol = OtlpExportProtocol.Grpc; private const string UserAgentProduct = "OTel-OTLP-Exporter-Dotnet"; private Uri endpoint; @@ -40,39 +44,27 @@ public class OtlpExporterOptions /// Initializes a new instance of the class. /// public OtlpExporterOptions() - : this(new ConfigurationBuilder().AddEnvironmentVariables().Build(), new()) + : this(OtlpExporterOptionsConfigurationType.Default) + { + } + + internal OtlpExporterOptions( + OtlpExporterOptionsConfigurationType configurationType) + : this( + configuration: new ConfigurationBuilder().AddEnvironmentVariables().Build(), + configurationType, + defaultBatchOptions: new()) { } internal OtlpExporterOptions( IConfiguration configuration, + OtlpExporterOptionsConfigurationType configurationType, BatchExportActivityProcessorOptions defaultBatchOptions) { - Debug.Assert(configuration != null, "configuration was null"); Debug.Assert(defaultBatchOptions != null, "defaultBatchOptions was null"); - if (configuration.TryGetUriValue(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, out var endpoint)) - { - this.endpoint = endpoint; - } - - if (configuration.TryGetStringValue(OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName, out var headers)) - { - this.Headers = headers; - } - - if (configuration.TryGetIntValue(OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName, out var timeout)) - { - this.TimeoutMilliseconds = timeout; - } - - if (configuration.TryGetValue( - OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName, - OtlpExportProtocolParser.TryParse, - out var protocol)) - { - this.Protocol = protocol; - } + this.ApplyConfiguration(configuration, configurationType); this.HttpClientFactory = this.DefaultHttpClientFactory = () => { @@ -98,7 +90,7 @@ public Uri Endpoint { if (this.endpoint == null) { - this.endpoint = this.Protocol == OtlpExportProtocol.Grpc + return this.Protocol == OtlpExportProtocol.Grpc ? new Uri(DefaultGrpcEndpoint) : new Uri(DefaultHttpEndpoint); } @@ -195,8 +187,42 @@ internal static OtlpExporterOptions CreateOtlpExporterOptions( string name) => new( configuration, + OtlpExporterOptionsConfigurationType.Default, serviceProvider.GetRequiredService>().Get(name)); + internal void ApplyConfigurationUsingSpecificationEnvVars( + IConfiguration configuration, + string endpointEnvVarKey, + bool appendSignalPathToEndpoint, + string protocolEnvVarKey, + string headersEnvVarKey, + string timeoutEnvVarKey) + { + if (configuration.TryGetUriValue(endpointEnvVarKey, out var endpoint)) + { + this.endpoint = endpoint; + this.AppendSignalPathToEndpoint = appendSignalPathToEndpoint; + } + + if (configuration.TryGetValue( + protocolEnvVarKey, + OtlpExportProtocolParser.TryParse, + out var protocol)) + { + this.Protocol = protocol; + } + + if (configuration.TryGetStringValue(headersEnvVarKey, out var headers)) + { + this.Headers = headers; + } + + if (configuration.TryGetIntValue(timeoutEnvVarKey, out var timeout)) + { + this.TimeoutMilliseconds = timeout; + } + } + private static string GetUserAgentString() { try @@ -210,4 +236,60 @@ private static string GetUserAgentString() return UserAgentProduct; } } + + private void ApplyConfiguration( + IConfiguration configuration, + OtlpExporterOptionsConfigurationType configurationType) + { + Debug.Assert(configuration != null, "configuration was null"); + + // Note: When using the "AddOtlpExporter" extensions configurationType + // never has a value other than "Default" because OtlpExporterOptions is + // shared by all signals and there is no way to differentiate which + // signal is being constructed. + if (configurationType == OtlpExporterOptionsConfigurationType.Default) + { + this.ApplyConfigurationUsingSpecificationEnvVars( + configuration!, + OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName, + appendSignalPathToEndpoint: true, + OtlpSpecConfigDefinitions.DefaultProtocolEnvVarName, + OtlpSpecConfigDefinitions.DefaultHeadersEnvVarName, + OtlpSpecConfigDefinitions.DefaultTimeoutEnvVarName); + } + else if (configurationType == OtlpExporterOptionsConfigurationType.Logs) + { + this.ApplyConfigurationUsingSpecificationEnvVars( + configuration!, + OtlpSpecConfigDefinitions.LogsEndpointEnvVarName, + appendSignalPathToEndpoint: false, + OtlpSpecConfigDefinitions.LogsProtocolEnvVarName, + OtlpSpecConfigDefinitions.LogsHeadersEnvVarName, + OtlpSpecConfigDefinitions.LogsTimeoutEnvVarName); + } + else if (configurationType == OtlpExporterOptionsConfigurationType.Metrics) + { + this.ApplyConfigurationUsingSpecificationEnvVars( + configuration!, + OtlpSpecConfigDefinitions.MetricsEndpointEnvVarName, + appendSignalPathToEndpoint: false, + OtlpSpecConfigDefinitions.MetricsProtocolEnvVarName, + OtlpSpecConfigDefinitions.MetricsHeadersEnvVarName, + OtlpSpecConfigDefinitions.MetricsTimeoutEnvVarName); + } + else if (configurationType == OtlpExporterOptionsConfigurationType.Traces) + { + this.ApplyConfigurationUsingSpecificationEnvVars( + configuration!, + OtlpSpecConfigDefinitions.TracesEndpointEnvVarName, + appendSignalPathToEndpoint: false, + OtlpSpecConfigDefinitions.TracesProtocolEnvVarName, + OtlpSpecConfigDefinitions.TracesHeadersEnvVarName, + OtlpSpecConfigDefinitions.TracesTimeoutEnvVarName); + } + else + { + throw new NotSupportedException($"OtlpExporterOptionsConfigurationType '{configurationType}' is not supported."); + } + } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs index 747cf46f949..37a66dc2f10 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs @@ -63,7 +63,7 @@ public static MeterProviderBuilder AddOtlpExporter( services.AddOptions(finalOptionsName).Configure( (readerOptions, config) => { - var otlpTemporalityPreference = config[OtlpExporterSpecEnvVarKeyDefinitions.MetricsTemporalityPreferenceEnvVarName]; + var otlpTemporalityPreference = config[OtlpSpecConfigDefinitions.MetricsTemporalityPreferenceEnvVarName]; if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference) && Enum.TryParse(otlpTemporalityPreference, ignoreCase: true, out var enumValue)) { @@ -140,7 +140,7 @@ public static MeterProviderBuilder AddOtlpExporter( services.AddOptions(finalOptionsName).Configure( (readerOptions, config) => { - var otlpTemporalityPreference = config[OtlpExporterSpecEnvVarKeyDefinitions.MetricsTemporalityPreferenceEnvVarName]; + var otlpTemporalityPreference = config[OtlpSpecConfigDefinitions.MetricsTemporalityPreferenceEnvVarName]; if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference) && Enum.TryParse(otlpTemporalityPreference, ignoreCase: true, out var enumValue)) { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs index 4a419463b6d..a846af33a4e 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/BaseOtlpHttpExportClientTests.cs @@ -21,7 +21,7 @@ public void ValidateOtlpHttpExportClientEndpoint(string optionEndpoint, string e { try { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, endpointEnvVar); + Environment.SetEnvironmentVariable(OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName, endpointEnvVar); OtlpExporterOptions options = new() { Protocol = OtlpExportProtocol.HttpProtobuf }; @@ -35,7 +35,7 @@ public void ValidateOtlpHttpExportClientEndpoint(string optionEndpoint, string e } finally { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, null); + Environment.SetEnvironmentVariable(OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName, null); } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs index f567ed118e1..4ba49ec760a 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs @@ -13,6 +13,49 @@ public OtlpExporterOptionsTests() ClearEnvVars(); } + public static IEnumerable GetOtlpExporterOptionsTestCases() + { + yield return new object[] + { + OtlpExporterOptionsConfigurationType.Default, + OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName, + OtlpSpecConfigDefinitions.DefaultHeadersEnvVarName, + OtlpSpecConfigDefinitions.DefaultTimeoutEnvVarName, + OtlpSpecConfigDefinitions.DefaultProtocolEnvVarName, + true, + }; + + yield return new object[] + { + OtlpExporterOptionsConfigurationType.Logs, + OtlpSpecConfigDefinitions.LogsEndpointEnvVarName, + OtlpSpecConfigDefinitions.LogsHeadersEnvVarName, + OtlpSpecConfigDefinitions.LogsTimeoutEnvVarName, + OtlpSpecConfigDefinitions.LogsProtocolEnvVarName, + false, + }; + + yield return new object[] + { + OtlpExporterOptionsConfigurationType.Metrics, + OtlpSpecConfigDefinitions.MetricsEndpointEnvVarName, + OtlpSpecConfigDefinitions.MetricsHeadersEnvVarName, + OtlpSpecConfigDefinitions.MetricsTimeoutEnvVarName, + OtlpSpecConfigDefinitions.MetricsProtocolEnvVarName, + false, + }; + + yield return new object[] + { + OtlpExporterOptionsConfigurationType.Traces, + OtlpSpecConfigDefinitions.TracesEndpointEnvVarName, + OtlpSpecConfigDefinitions.TracesHeadersEnvVarName, + OtlpSpecConfigDefinitions.TracesTimeoutEnvVarName, + OtlpSpecConfigDefinitions.TracesProtocolEnvVarName, + false, + }; + } + public void Dispose() { ClearEnvVars(); @@ -24,10 +67,10 @@ public void OtlpExporterOptions_Defaults() { var options = new OtlpExporterOptions(); - Assert.Equal(new Uri("http://localhost:4317"), options.Endpoint); + Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint); Assert.Null(options.Headers); Assert.Equal(10000, options.TimeoutMilliseconds); - Assert.Equal(OtlpExportProtocol.Grpc, options.Protocol); + Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol); } [Fact] @@ -37,100 +80,153 @@ public void OtlpExporterOptions_DefaultsForHttpProtobuf() { Protocol = OtlpExportProtocol.HttpProtobuf, }; - Assert.Equal(new Uri("http://localhost:4318"), options.Endpoint); + Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint); Assert.Null(options.Headers); Assert.Equal(10000, options.TimeoutMilliseconds); Assert.Equal(OtlpExportProtocol.HttpProtobuf, options.Protocol); } - [Fact] - public void OtlpExporterOptions_EnvironmentVariableOverride() + [Theory] + [MemberData(nameof(GetOtlpExporterOptionsTestCases))] + public void OtlpExporterOptions_EnvironmentVariableOverride( + int configurationType, + string endpointEnvVarKeyName, + string headersEnvVarKeyName, + string timeoutEnvVarKeyName, + string protocolEnvVarKeyName, + bool appendSignalPathToEndpoint) { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, "http://test:8888"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName, "A=2,B=3"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName, "2000"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName, "http/protobuf"); + Environment.SetEnvironmentVariable(endpointEnvVarKeyName, "http://test:8888"); + Environment.SetEnvironmentVariable(headersEnvVarKeyName, "A=2,B=3"); + Environment.SetEnvironmentVariable(timeoutEnvVarKeyName, "2000"); + Environment.SetEnvironmentVariable(protocolEnvVarKeyName, "http/protobuf"); - var options = new OtlpExporterOptions(); + var options = new OtlpExporterOptions((OtlpExporterOptionsConfigurationType)configurationType); Assert.Equal(new Uri("http://test:8888"), options.Endpoint); Assert.Equal("A=2,B=3", options.Headers); Assert.Equal(2000, options.TimeoutMilliseconds); Assert.Equal(OtlpExportProtocol.HttpProtobuf, options.Protocol); + Assert.Equal(appendSignalPathToEndpoint, options.AppendSignalPathToEndpoint); } - [Fact] - public void OtlpExporterOptions_UsingIConfiguration() + [Theory] + [MemberData(nameof(GetOtlpExporterOptionsTestCases))] + public void OtlpExporterOptions_UsingIConfiguration( + int configurationType, + string endpointEnvVarKeyName, + string headersEnvVarKeyName, + string timeoutEnvVarKeyName, + string protocolEnvVarKeyName, + bool appendSignalPathToEndpoint) { var values = new Dictionary() { - [OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName] = "http://test:8888", - [OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName] = "A=2,B=3", - [OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName] = "2000", - [OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName] = "http/protobuf", + [endpointEnvVarKeyName] = "http://test:8888", + [headersEnvVarKeyName] = "A=2,B=3", + [timeoutEnvVarKeyName] = "2000", + [protocolEnvVarKeyName] = "http/protobuf", }; var configuration = new ConfigurationBuilder() .AddInMemoryCollection(values) .Build(); - var options = new OtlpExporterOptions(configuration, new()); + var options = new OtlpExporterOptions(configuration, (OtlpExporterOptionsConfigurationType)configurationType, new()); Assert.Equal(new Uri("http://test:8888"), options.Endpoint); Assert.Equal("A=2,B=3", options.Headers); Assert.Equal(2000, options.TimeoutMilliseconds); Assert.Equal(OtlpExportProtocol.HttpProtobuf, options.Protocol); + Assert.Equal(appendSignalPathToEndpoint, options.AppendSignalPathToEndpoint); } [Fact] public void OtlpExporterOptions_InvalidEnvironmentVariableOverride() { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, "invalid"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName, "invalid"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName, "invalid"); + var values = new Dictionary() + { + ["EndpointWithInvalidValue"] = "invalid", + ["TimeoutWithInvalidValue"] = "invalid", + ["ProtocolWithInvalidValue"] = "invalid", + }; + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(values) + .Build(); var options = new OtlpExporterOptions(); - Assert.Equal(new Uri("http://localhost:4317"), options.Endpoint); + options.ApplyConfigurationUsingSpecificationEnvVars( + configuration, + "EndpointWithInvalidValue", + appendSignalPathToEndpoint: true, + "ProtocolWithInvalidValue", + "NoopHeaders", + "TimeoutWithInvalidValue"); + + Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint); Assert.Equal(10000, options.TimeoutMilliseconds); - Assert.Equal(default, options.Protocol); + Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol); + Assert.Null(options.Headers); } [Fact] public void OtlpExporterOptions_SetterOverridesEnvironmentVariable() { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, "http://test:8888"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName, "A=2,B=3"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName, "2000"); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName, "grpc"); - - var options = new OtlpExporterOptions + var values = new Dictionary() { - Endpoint = new Uri("http://localhost:200"), - Headers = "C=3", - TimeoutMilliseconds = 40000, - Protocol = OtlpExportProtocol.HttpProtobuf, + ["Endpoint"] = "http://test:8888", + ["Timeout"] = "2000", + ["Protocol"] = "grpc", + ["Headers"] = "A=2,B=3", }; + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(values) + .Build(); + + var options = new OtlpExporterOptions(); + + options.ApplyConfigurationUsingSpecificationEnvVars( + configuration, + "Endpoint", + appendSignalPathToEndpoint: true, + "Protocol", + "Headers", + "Timeout"); + + options.Endpoint = new Uri("http://localhost:200"); + options.Headers = "C=3"; + options.TimeoutMilliseconds = 40000; + options.Protocol = OtlpExportProtocol.HttpProtobuf; + Assert.Equal(new Uri("http://localhost:200"), options.Endpoint); Assert.Equal("C=3", options.Headers); Assert.Equal(40000, options.TimeoutMilliseconds); Assert.Equal(OtlpExportProtocol.HttpProtobuf, options.Protocol); + Assert.False(options.AppendSignalPathToEndpoint); } [Fact] - public void OtlpExporterOptions_ProtocolSetterDoesNotOverrideCustomEndpointFromEnvVariables() + public void OtlpExporterOptions_EndpointGetterUsesProtocolWhenNull() { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, "http://test:8888"); + var options = new OtlpExporterOptions(); - var options = new OtlpExporterOptions { Protocol = OtlpExportProtocol.Grpc }; + Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint); + Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol); - Assert.Equal(new Uri("http://test:8888"), options.Endpoint); - Assert.Equal(OtlpExportProtocol.Grpc, options.Protocol); + options.Protocol = OtlpExportProtocol.HttpProtobuf; + + Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint); + + options.Protocol = OtlpExportProtocol.Grpc; + + Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint); } [Fact] - public void OtlpExporterOptions_ProtocolSetterDoesNotOverrideCustomEndpointFromSetter() + public void OtlpExporterOptions_EndpointGetterIgnoresProtocolWhenNotNull() { var options = new OtlpExporterOptions { Endpoint = new Uri("http://test:8888"), Protocol = OtlpExportProtocol.Grpc }; @@ -141,17 +237,20 @@ public void OtlpExporterOptions_ProtocolSetterDoesNotOverrideCustomEndpointFromS [Fact] public void OtlpExporterOptions_EnvironmentVariableNames() { - Assert.Equal("OTEL_EXPORTER_OTLP_ENDPOINT", OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName); - Assert.Equal("OTEL_EXPORTER_OTLP_HEADERS", OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName); - Assert.Equal("OTEL_EXPORTER_OTLP_TIMEOUT", OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName); - Assert.Equal("OTEL_EXPORTER_OTLP_PROTOCOL", OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName); + Assert.Equal("OTEL_EXPORTER_OTLP_ENDPOINT", OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName); + Assert.Equal("OTEL_EXPORTER_OTLP_HEADERS", OtlpSpecConfigDefinitions.DefaultHeadersEnvVarName); + Assert.Equal("OTEL_EXPORTER_OTLP_TIMEOUT", OtlpSpecConfigDefinitions.DefaultTimeoutEnvVarName); + Assert.Equal("OTEL_EXPORTER_OTLP_PROTOCOL", OtlpSpecConfigDefinitions.DefaultProtocolEnvVarName); } private static void ClearEnvVars() { - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName, null); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultHeadersEnvVarName, null); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultTimeoutEnvVarName, null); - Environment.SetEnvironmentVariable(OtlpExporterSpecEnvVarKeyDefinitions.DefaultProtocolEnvVarName, null); + foreach (var item in GetOtlpExporterOptionsTestCases()) + { + Environment.SetEnvironmentVariable((string)item[1], null); + Environment.SetEnvironmentVariable((string)item[2], null); + Environment.SetEnvironmentVariable((string)item[3], null); + Environment.SetEnvironmentVariable((string)item[4], null); + } } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index 6ad2ff04686..87a6011f2f5 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -1517,7 +1517,7 @@ private static void RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( { var values = new Dictionary() { - [OtlpExporterSpecEnvVarKeyDefinitions.DefaultEndpointEnvVarName] = "http://test:8888", + [OtlpSpecConfigDefinitions.DefaultEndpointEnvVarName] = "http://test:8888", }; var configuration = new ConfigurationBuilder()