diff --git a/examples/Console/TestLogs.cs b/examples/Console/TestLogs.cs index 13a7b7f60e7..4c88753ffd7 100644 --- a/examples/Console/TestLogs.cs +++ b/examples/Console/TestLogs.cs @@ -41,11 +41,6 @@ internal static object Run(LogsOptions options) * */ - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure gRPC service. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - var protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc; if (options.Protocol.Trim().ToLower().Equals("grpc")) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 2ed64c25272..535403998ab 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* `OtlpExporter` will no longer throw an exception (even on .NET Core 3.1) + when the `System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport` + `AppContext` switch is NOT set AND using `OtlpExportProtocol.Grpc` + to send to an insecure ("http") endpoint. + `System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport` + is not required to be set [when using .NET 5 or newer](https://learn.microsoft.com/aspnet/core/grpc/troubleshoot?view=aspnetcore-8.0#call-insecure-grpc-services-with-net-core-client). + ([#5486](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5486)) + ## 1.8.0-rc.1 Released 2024-Mar-27 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpGrpcExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpGrpcExportClient.cs index 5565c9ca8ca..493d267bc74 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpGrpcExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpGrpcExportClient.cs @@ -20,8 +20,6 @@ protected BaseOtlpGrpcExportClient(OtlpExporterOptions options) Guard.ThrowIfNull(options); Guard.ThrowIfInvalidTimeout(options.TimeoutMilliseconds); - ExporterClientValidation.EnsureUnencryptedSupportIsEnabled(options); - this.Endpoint = new UriBuilder(options.Endpoint).Uri; this.Headers = options.GetMetadataFromHeaders(); this.TimeoutMilliseconds = options.TimeoutMilliseconds; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/ExporterClientValidation.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/ExporterClientValidation.cs deleted file mode 100644 index 87b817e05e5..00000000000 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/ExporterClientValidation.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; - -internal static class ExporterClientValidation -{ - internal static void EnsureUnencryptedSupportIsEnabled(OtlpExporterOptions options) - { - var version = Environment.Version; - - // This verification is only required for .NET Core 3.x - if (version.Major != 3) - { - return; - } - - if (options.Endpoint.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase)) - { - if (AppContext.TryGetSwitch( - "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", out var unencryptedIsSupported) == false - || unencryptedIsSupported == false) - { - throw new InvalidOperationException( - "Calling insecure gRPC services on .NET Core 3.x requires enabling the 'System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport' switch. See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client"); - } - } - } -} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/ExporterClientValidationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/ExporterClientValidationTests.cs deleted file mode 100644 index e7c1a0b2d7a..00000000000 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/ExporterClientValidationTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; -using Xunit; - -namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; - -public class ExporterClientValidationTests : Http2UnencryptedSupportTests -{ - private const string HttpEndpoint = "http://localhost:4173"; - private const string HttpsEndpoint = "https://localhost:4173"; - - [Fact] - public void ExporterClientValidation_FlagIsEnabledForHttpEndpoint() - { - var options = new OtlpExporterOptions - { - Endpoint = new Uri(HttpEndpoint), - }; - - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - - var exception = Record.Exception(() => ExporterClientValidation.EnsureUnencryptedSupportIsEnabled(options)); - Assert.Null(exception); - } - - [Fact] - public void ExporterClientValidation_FlagIsNotEnabledForHttpEndpoint() - { - var options = new OtlpExporterOptions - { - Endpoint = new Uri(HttpEndpoint), - }; - - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); - - var exception = Record.Exception(() => ExporterClientValidation.EnsureUnencryptedSupportIsEnabled(options)); - - if (Environment.Version.Major == 3) - { - Assert.NotNull(exception); - Assert.IsType(exception); - } - else - { - Assert.Null(exception); - } - } - - [Fact] - public void ExporterClientValidation_FlagIsNotEnabledForHttpsEndpoint() - { - var options = new OtlpExporterOptions - { - Endpoint = new Uri(HttpsEndpoint), - }; - - var exception = Record.Exception(() => ExporterClientValidation.EnsureUnencryptedSupportIsEnabled(options)); - Assert.Null(exception); - } -} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs deleted file mode 100644 index 7ef14595f06..00000000000 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Http2UnencryptedSupportTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; - -public class Http2UnencryptedSupportTests : IDisposable -{ - private readonly bool initialFlagStatus; - - public Http2UnencryptedSupportTests() - { - this.initialFlagStatus = DetermineInitialFlagStatus(); - } - - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", this.initialFlagStatus); - } - - private static bool DetermineInitialFlagStatus() - { - if (AppContext.TryGetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", out var flag)) - { - return flag; - } - - return false; - } -} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs index 49c0e054237..9fbe4b5703a 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs @@ -278,33 +278,6 @@ public void LogExportResultIsSuccess(OtlpExportProtocol protocol, string endpoin } } - [Trait("CategoryName", "CollectorIntegrationTests")] - [SkipUnlessEnvVarFoundFact(CollectorHostnameEnvVarName)] - public void ConstructingGrpcExporterFailsWhenHttp2UnencryptedSupportIsDisabledForNetcoreapp31() - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service. - // We want to fail fast so we are disabling it - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); - - var exporterOptions = new OtlpExporterOptions - { - Endpoint = new Uri($"http://{CollectorHostname}:4317"), - }; - - var exception = Record.Exception(() => new OtlpTraceExporter(exporterOptions)); - - if (Environment.Version.Major == 3) - { - Assert.NotNull(exception); - } - else - { - Assert.Null(exception); - } - } - private sealed class OpenTelemetryEventListener : EventListener { private readonly ITestOutputHelper outputHelper; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs index 07d7a92612c..b4b2917491b 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; -public class OtlpExportProtocolParserTests : Http2UnencryptedSupportTests +public class OtlpExportProtocolParserTests { [Theory] [InlineData("grpc", true, OtlpExportProtocol.Grpc)] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs index 55d9e092bb7..b8bfb608288 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs @@ -12,7 +12,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; -public class OtlpExporterOptionsExtensionsTests : Http2UnencryptedSupportTests +public class OtlpExporterOptionsExtensionsTests { [Theory] [InlineData("key=value", new string[] { "key" }, new string[] { "value" })] @@ -94,14 +94,6 @@ public void GetHeaders_NoOptionHeaders_ReturnsStandardHeaders(string optionHeade [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpTraceExportClient))] public void GetTraceExportClient_SupportedProtocol_ReturnsCorrectExportClient(OtlpExportProtocol protocol, Type expectedExportClientType) { - if (protocol == OtlpExportProtocol.Grpc && Environment.Version.Major == 3) - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure HTTP/2 endpoint. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - } - var options = new OtlpExporterOptions { Protocol = protocol, @@ -112,32 +104,6 @@ public void GetTraceExportClient_SupportedProtocol_ReturnsCorrectExportClient(Ot Assert.Equal(expectedExportClientType, exportClient.GetType()); } - [Fact] - public void GetTraceExportClient_GetClientForGrpcWithoutUnencryptedFlag_ThrowsException() - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure HTTP/2 endpoint. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false); - - var options = new OtlpExporterOptions - { - Protocol = OtlpExportProtocol.Grpc, - }; - - var exception = Record.Exception(() => options.GetTraceExportClient()); - - if (Environment.Version.Major == 3) - { - Assert.NotNull(exception); - Assert.IsType(exception); - } - else - { - Assert.Null(exception); - } - } - [Fact] public void GetTraceExportClient_UnsupportedProtocol_Throws() { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index 92720ad0302..fd0ea958c28 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; -public class OtlpLogExporterTests : Http2UnencryptedSupportTests +public class OtlpLogExporterTests { private static readonly SdkLimitOptions DefaultSdkLimitOptions = new(); @@ -111,14 +111,6 @@ public void UserHttpFactoryCalledWhenUsingHttpProtobuf() [Fact] public void AddOtlpExporterSetsDefaultBatchExportProcessor() { - if (Environment.Version.Major == 3) - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure HTTP/2 endpoint. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - } - var loggerProvider = Sdk.CreateLoggerProviderBuilder() .AddOtlpExporter() .Build(); @@ -152,7 +144,6 @@ public void AddOtlpLogExporterReceivesAttributesWithParseStateValueSetToFalse() { bool optionsValidated = false; - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { @@ -185,7 +176,6 @@ public void AddOtlpLogExporterReceivesAttributesWithParseStateValueSetToFalse() [InlineData(false)] public void AddOtlpLogExporterParseStateValueCanBeTurnedOff(bool parseState) { - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); var logRecords = new List(); using var loggerFactory = LoggerFactory.Create(builder => { @@ -231,7 +221,6 @@ public void AddOtlpLogExporterParseStateValueCanBeTurnedOffHosting(bool parseSta { var logRecords = new List(); - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); var hostBuilder = new HostBuilder(); hostBuilder.ConfigureLogging(logging => logging .AddOpenTelemetry(options => options diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index ad2f8a6b4b2..07124e63a85 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -19,7 +19,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; [Collection("EnvVars")] -public class OtlpMetricsExporterTests : Http2UnencryptedSupportTests +public class OtlpMetricsExporterTests : IDisposable { private static readonly KeyValuePair[] KeyValues = new KeyValuePair[] { @@ -35,14 +35,6 @@ public OtlpMetricsExporterTests() [Fact] public void TestAddOtlpExporter_SetsCorrectMetricReaderDefaults() { - if (Environment.Version.Major == 3) - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure HTTP/2 endpoint. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - } - var meterProvider = Sdk.CreateMeterProviderBuilder() .AddOtlpExporter() .Build(); @@ -916,11 +908,10 @@ void AssertExemplars(T value, Metric metric) } } - protected override void Dispose(bool disposing) + public void Dispose() { OtlpSpecConfigDefinitionTests.ClearEnvVars(); - - base.Dispose(disposing); + GC.SuppressFinalize(this); } private static void VerifyExemplars(long? longValue, double? doubleValue, bool enableExemplars, Func getExemplarFunc, T state) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 1a06d7eca4f..ac099494f43 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -19,7 +19,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests; [Collection("xUnitCollectionPreventingTestsThatDependOnSdkConfigurationFromRunningInParallel")] -public class OtlpTraceExporterTests : Http2UnencryptedSupportTests +public class OtlpTraceExporterTests { private static readonly SdkLimitOptions DefaultSdkLimitOptions = new(); @@ -581,14 +581,6 @@ public void ToOtlpSpanPeerServiceTest() [Fact] public void UseOpenTelemetryProtocolActivityExporterWithCustomActivityProcessor() { - if (Environment.Version.Major == 3) - { - // Adding the OtlpExporter creates a GrpcChannel. - // This switch must be set before creating a GrpcChannel when calling an insecure HTTP/2 endpoint. - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - } - const string ActivitySourceName = "otlp.test"; TestActivityProcessor testActivityProcessor = new TestActivityProcessor();