diff --git a/Directory.Packages.props b/Directory.Packages.props
index 7f7418ea3b0..bf588e7ddde 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -57,15 +57,6 @@
even during major version bumps, so compatibility is not a concern here.
-->
-
-
-
-
-
-
@@ -97,6 +88,9 @@
+
+
+
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
index 71e0e5899ac..08ae5ab9b67 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
@@ -7,6 +7,16 @@ Notes](../../RELEASENOTES.md).
## Unreleased
+* **Breaking Change**: .NET Framework and .NET Standard builds now default to
+ exporting over OTLP/HTTP instead of OTLP/gRPC. **This change could result in a
+ failure to export telemetry unless appropriate measures are taken.**
+ Additionally, if you explicitly configure the exporter to use OTLP/gRPC it may
+ result in a `NotSupportedException` without further configuration. Please
+ carefully review issue
+ ([#6209](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6209))
+ for additional information and workarounds.
+ ([#6229](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6229))
+
## 1.11.2
Released 2025-Mar-04
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/GrpcExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/GrpcExportClient.cs
deleted file mode 100644
index c3c0c8012c9..00000000000
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/GrpcExportClient.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if NET462_OR_GREATER || NETSTANDARD2_0
-using Grpc.Core;
-using OpenTelemetry.Internal;
-
-using InternalStatus = OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient.Grpc.Status;
-using InternalStatusCode = OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient.Grpc.StatusCode;
-using Status = Grpc.Core.Status;
-using StatusCode = Grpc.Core.StatusCode;
-
-namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
-
-internal sealed class GrpcExportClient : IExportClient
-{
- private static readonly ExportClientGrpcResponse SuccessExportResponse = new(
- success: true,
- deadlineUtc: default,
- exception: null,
- status: null,
- grpcStatusDetailsHeader: null);
-
- private static readonly Marshaller ByteArrayMarshaller = Marshallers.Create(
- serializer: static input => input,
- deserializer: static data => data);
-
- private readonly Method exportMethod;
-
- private readonly CallInvoker callInvoker;
-
- public GrpcExportClient(OtlpExporterOptions options, string signalPath)
- {
- Guard.ThrowIfNull(options);
- Guard.ThrowIfInvalidTimeout(options.TimeoutMilliseconds);
- Guard.ThrowIfNull(signalPath);
-
- var exporterEndpoint = options.Endpoint.AppendPathIfNotPresent(signalPath);
- this.Endpoint = new UriBuilder(exporterEndpoint).Uri;
- this.Channel = options.CreateChannel();
- this.Headers = options.GetMetadataFromHeaders();
-
- var serviceAndMethod = signalPath.Split('/');
- this.exportMethod = new Method(MethodType.Unary, serviceAndMethod[0], serviceAndMethod[1], ByteArrayMarshaller, ByteArrayMarshaller);
- this.callInvoker = this.Channel.CreateCallInvoker();
- }
-
- internal Channel Channel { get; }
-
- internal Uri Endpoint { get; }
-
- internal Metadata Headers { get; }
-
- public ExportClientResponse SendExportRequest(byte[] buffer, int contentLength, DateTime deadlineUtc, CancellationToken cancellationToken = default)
- {
- try
- {
- var contentSpan = buffer.AsSpan(0, contentLength);
- this.callInvoker?.BlockingUnaryCall(this.exportMethod, null, new CallOptions(this.Headers, deadlineUtc, cancellationToken), contentSpan.ToArray());
- return SuccessExportResponse;
- }
- catch (RpcException rpcException)
- {
- OpenTelemetryProtocolExporterEventSource.Log.FailedToReachCollector(this.Endpoint, rpcException);
- return new ExportClientGrpcResponse(success: false, deadlineUtc: deadlineUtc, exception: rpcException, ConvertGrpcStatusToStatus(rpcException.Status), rpcException.Trailers.ToString());
- }
- }
-
- public bool Shutdown(int timeoutMilliseconds)
- {
- if (this.Channel == null)
- {
- return true;
- }
-
- if (timeoutMilliseconds == -1)
- {
- this.Channel.ShutdownAsync().Wait();
- return true;
- }
- else
- {
- return Task.WaitAny([this.Channel.ShutdownAsync(), Task.Delay(timeoutMilliseconds)]) == 0;
- }
- }
-
- private static InternalStatus ConvertGrpcStatusToStatus(Status grpcStatus) => grpcStatus.StatusCode switch
- {
- StatusCode.OK => new InternalStatus(InternalStatusCode.OK, grpcStatus.Detail),
- StatusCode.Cancelled => new InternalStatus(InternalStatusCode.Cancelled, grpcStatus.Detail),
- StatusCode.Unknown => new InternalStatus(InternalStatusCode.Unknown, grpcStatus.Detail),
- StatusCode.InvalidArgument => new InternalStatus(InternalStatusCode.InvalidArgument, grpcStatus.Detail),
- StatusCode.DeadlineExceeded => new InternalStatus(InternalStatusCode.DeadlineExceeded, grpcStatus.Detail),
- StatusCode.NotFound => new InternalStatus(InternalStatusCode.NotFound, grpcStatus.Detail),
- StatusCode.AlreadyExists => new InternalStatus(InternalStatusCode.AlreadyExists, grpcStatus.Detail),
- StatusCode.PermissionDenied => new InternalStatus(InternalStatusCode.PermissionDenied, grpcStatus.Detail),
- StatusCode.Unauthenticated => new InternalStatus(InternalStatusCode.Unauthenticated, grpcStatus.Detail),
- StatusCode.ResourceExhausted => new InternalStatus(InternalStatusCode.ResourceExhausted, grpcStatus.Detail),
- StatusCode.FailedPrecondition => new InternalStatus(InternalStatusCode.FailedPrecondition, grpcStatus.Detail),
- StatusCode.Aborted => new InternalStatus(InternalStatusCode.Aborted, grpcStatus.Detail),
- StatusCode.OutOfRange => new InternalStatus(InternalStatusCode.OutOfRange, grpcStatus.Detail),
- StatusCode.Unimplemented => new InternalStatus(InternalStatusCode.Unimplemented, grpcStatus.Detail),
- StatusCode.Internal => new InternalStatus(InternalStatusCode.Internal, grpcStatus.Detail),
- StatusCode.Unavailable => new InternalStatus(InternalStatusCode.Unavailable, grpcStatus.Detail),
- StatusCode.DataLoss => new InternalStatus(InternalStatusCode.DataLoss, grpcStatus.Detail),
- _ => new InternalStatus(InternalStatusCode.Unknown, grpcStatus.Detail),
- };
-}
-#endif
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpExportClient.cs
index 7347c69b271..8e56ba88cbc 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpExportClient.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpExportClient.cs
@@ -35,7 +35,9 @@ protected OtlpExportClient(OtlpExporterOptions options, HttpClient httpClient, s
Guard.ThrowIfNull(signalPath);
Uri exporterEndpoint;
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
if (options.Protocol == OtlpExportProtocol.Grpc)
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
{
exporterEndpoint = options.Endpoint.AppendPathIfNotPresent(signalPath);
}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
index a29ba23649e..2277f25a16b 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
@@ -23,10 +23,6 @@
-
-
-
-
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocol.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocol.cs
index 10375e1dfc6..806d3b9defc 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocol.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocol.cs
@@ -11,6 +11,9 @@ public enum OtlpExportProtocol : byte
///
/// OTLP over gRPC (corresponds to 'grpc' Protocol configuration option). Used as default.
///
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ [Obsolete("CAUTION: OTLP/gRPC is no longer supported for .NET Framework or .NET Standard targets without supplying a properly configured HttpClientFactory. It is strongly encouraged that you migrate to using OTLP/HTTPPROTOBUF.")]
+#endif
Grpc = 0,
///
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocolParser.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocolParser.cs
index e5e788c5617..563c6b8a6b8 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocolParser.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExportProtocolParser.cs
@@ -10,7 +10,9 @@ public static bool TryParse(string value, out OtlpExportProtocol result)
switch (value?.Trim())
{
case "grpc":
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
result = OtlpExportProtocol.Grpc;
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
return true;
case "http/protobuf":
result = OtlpExportProtocol.HttpProtobuf;
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
index 355ab376743..91ebfdbd3e1 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
@@ -26,7 +26,11 @@ public class OtlpExporterOptions : IOtlpExporterOptions
{
internal const string DefaultGrpcEndpoint = "http://localhost:4317";
internal const string DefaultHttpEndpoint = "http://localhost:4318";
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ internal const OtlpExportProtocol DefaultOtlpExportProtocol = OtlpExportProtocol.HttpProtobuf;
+#else
internal const OtlpExportProtocol DefaultOtlpExportProtocol = OtlpExportProtocol.Grpc;
+#endif
internal static readonly KeyValuePair[] StandardHeaders = new KeyValuePair[]
{
@@ -84,7 +88,9 @@ public Uri Endpoint
{
if (this.endpoint == null)
{
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
return this.Protocol == OtlpExportProtocol.Grpc
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
? new Uri(DefaultGrpcEndpoint)
: new Uri(DefaultHttpEndpoint);
}
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs
index 8a2956939db..73ac888cc68 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs
@@ -9,9 +9,6 @@
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission;
-#if NET462_OR_GREATER || NETSTANDARD2_0
-using Grpc.Core;
-#endif
namespace OpenTelemetry.Exporter;
@@ -25,30 +22,6 @@ internal static class OtlpExporterOptionsExtensions
private const string MetricsHttpServicePath = "v1/metrics";
private const string LogsHttpServicePath = "v1/logs";
-#if NET462_OR_GREATER || NETSTANDARD2_0
- public static Channel CreateChannel(this OtlpExporterOptions options)
- {
- if (options.Endpoint.Scheme != Uri.UriSchemeHttp && options.Endpoint.Scheme != Uri.UriSchemeHttps)
- {
- throw new NotSupportedException($"Endpoint URI scheme ({options.Endpoint.Scheme}) is not supported. Currently only \"http\" and \"https\" are supported.");
- }
-
- ChannelCredentials channelCredentials;
- if (options.Endpoint.Scheme == Uri.UriSchemeHttps)
- {
- channelCredentials = new SslCredentials();
- }
- else
- {
- channelCredentials = ChannelCredentials.Insecure;
- }
-
- return new Channel(options.Endpoint.Authority, channelCredentials);
- }
-
- public static Metadata GetMetadataFromHeaders(this OtlpExporterOptions options) => options.GetHeaders((m, k, v) => m.Add(k, v));
-#endif
-
public static THeaders GetHeaders(this OtlpExporterOptions options, Action addHeader)
where THeaders : new()
{
@@ -129,25 +102,12 @@ public static IExportClient GetExportClient(this OtlpExporterOptions options, Ot
{
var httpClient = options.HttpClientFactory?.Invoke() ?? throw new InvalidOperationException("OtlpExporterOptions was missing HttpClientFactory or it returned null.");
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
if (options.Protocol != OtlpExportProtocol.Grpc && options.Protocol != OtlpExportProtocol.HttpProtobuf)
{
throw new NotSupportedException($"Protocol {options.Protocol} is not supported.");
}
-#if NET462_OR_GREATER || NETSTANDARD2_0
- if (options.Protocol == OtlpExportProtocol.Grpc)
- {
- var servicePath = otlpSignalType switch
- {
- OtlpSignalType.Traces => TraceGrpcServicePath,
- OtlpSignalType.Metrics => MetricsGrpcServicePath,
- OtlpSignalType.Logs => LogsGrpcServicePath,
- _ => throw new NotSupportedException($"OtlpSignalType {otlpSignalType} is not supported."),
- };
- return new GrpcExportClient(options, servicePath);
- }
-#endif
-
return otlpSignalType switch
{
OtlpSignalType.Traces => options.Protocol == OtlpExportProtocol.Grpc
@@ -164,6 +124,7 @@ public static IExportClient GetExportClient(this OtlpExporterOptions options, Ot
_ => throw new NotSupportedException($"OtlpSignalType {otlpSignalType} is not supported."),
};
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
}
public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptions options, IServiceProvider serviceProvider, string httpClientName)
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
index 42faf425356..1d69cfff851 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporterHelperExtensions.cs
@@ -284,6 +284,17 @@ internal static BaseProcessor BuildOtlpLogExporter(
Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null");
Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+#if NET462_OR_GREATER || NETSTANDARD2_0
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
+ if (exporterOptions!.Protocol == OtlpExportProtocol.Grpc &&
+ ReferenceEquals(exporterOptions.HttpClientFactory, exporterOptions.DefaultHttpClientFactory))
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
+ {
+ throw new NotSupportedException("OtlpExportProtocol.Grpc with the default HTTP client factory is not supported on .NET Framework or .NET Standard 2.0." +
+ "Please switch to OtlpExportProtocol.HttpProtobuf or provide a custom HttpClientFactory.");
+ }
+#endif
+
if (!skipUseOtlpExporterRegistrationCheck)
{
serviceProvider!.EnsureNoUseOtlpExporterRegistrations();
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
index 1a8ef2f1b42..2a08c7d0a1a 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs
@@ -168,6 +168,17 @@ internal static MetricReader BuildOtlpExporterMetricReader(
Debug.Assert(metricReaderOptions != null, "metricReaderOptions was null");
Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
+#if NET462_OR_GREATER || NETSTANDARD2_0
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
+ if (exporterOptions!.Protocol == OtlpExportProtocol.Grpc &&
+ ReferenceEquals(exporterOptions.HttpClientFactory, exporterOptions.DefaultHttpClientFactory))
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
+ {
+ throw new NotSupportedException("OtlpExportProtocol.Grpc with the default HTTP client factory is not supported on .NET Framework or .NET Standard 2.0." +
+ "Please switch to OtlpExportProtocol.HttpProtobuf or provide a custom HttpClientFactory.");
+ }
+#endif
+
if (!skipUseOtlpExporterRegistrationCheck)
{
serviceProvider!.EnsureNoUseOtlpExporterRegistrations();
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
index 3a18b3da423..f892201983b 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs
@@ -129,6 +129,17 @@ internal static BaseProcessor BuildOtlpExporterProcessor(
Debug.Assert(experimentalOptions != null, "experimentalOptions was null");
Debug.Assert(batchExportProcessorOptions != null, "batchExportProcessorOptions was null");
+#if NET462_OR_GREATER || NETSTANDARD2_0
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
+ if (exporterOptions!.Protocol == OtlpExportProtocol.Grpc &&
+ ReferenceEquals(exporterOptions.HttpClientFactory, exporterOptions.DefaultHttpClientFactory))
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
+ {
+ throw new NotSupportedException("OtlpExportProtocol.Grpc with the default HTTP client factory is not supported on .NET Framework or .NET Standard 2.0." +
+ "Please switch to OtlpExportProtocol.HttpProtobuf or provide a custom HttpClientFactory.");
+ }
+#endif
+
if (!skipUseOtlpExporterRegistrationCheck)
{
serviceProvider!.EnsureNoUseOtlpExporterRegistrations();
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
index 3e40b9c6d9f..eb97a2260ec 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTest/IntegrationTests.cs
@@ -34,6 +34,7 @@ public void Dispose()
this.openTelemetryEventListener.Dispose();
}
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc, ":4317", ExportProcessorType.Batch, false)]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/traces", ExportProcessorType.Batch, false)]
[InlineData(OtlpExportProtocol.Grpc, ":4317", ExportProcessorType.Batch, true)]
@@ -44,6 +45,7 @@ public void Dispose()
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/traces", ExportProcessorType.Simple, true)]
[InlineData(OtlpExportProtocol.Grpc, ":5317", ExportProcessorType.Simple, true, "https")]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":5318/v1/traces", ExportProcessorType.Simple, true, "https")]
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[Trait("CategoryName", "CollectorIntegrationTests")]
[SkipUnlessEnvVarFoundTheory(CollectorHostnameEnvVarName)]
public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpoint, ExportProcessorType exportProcessorType, bool forceFlush, string scheme = "http")
@@ -118,6 +120,7 @@ public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpo
}
}
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc, ":4317", false, false)]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/metrics", false, false)]
[InlineData(OtlpExportProtocol.Grpc, ":4317", false, true)]
@@ -128,6 +131,7 @@ public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpo
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/metrics", true, true)]
[InlineData(OtlpExportProtocol.Grpc, ":5317", true, true, "https")]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":5318/v1/metrics", true, true, "https")]
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[Trait("CategoryName", "CollectorIntegrationTests")]
[SkipUnlessEnvVarFoundTheory(CollectorHostnameEnvVarName)]
public void MetricExportResultIsSuccess(OtlpExportProtocol protocol, string endpoint, bool useManualExport, bool forceFlush, string scheme = "http")
@@ -202,12 +206,14 @@ public void MetricExportResultIsSuccess(OtlpExportProtocol protocol, string endp
}
}
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc, ":4317", ExportProcessorType.Batch)]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/logs", ExportProcessorType.Batch)]
[InlineData(OtlpExportProtocol.Grpc, ":4317", ExportProcessorType.Simple)]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":4318/v1/logs", ExportProcessorType.Simple)]
[InlineData(OtlpExportProtocol.Grpc, ":5317", ExportProcessorType.Simple, "https")]
[InlineData(OtlpExportProtocol.HttpProtobuf, ":5318/v1/logs", ExportProcessorType.Simple, "https")]
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[Trait("CategoryName", "CollectorIntegrationTests")]
[SkipUnlessEnvVarFoundTheory(CollectorHostnameEnvVarName)]
public void LogExportResultIsSuccess(OtlpExportProtocol protocol, string endpoint, ExportProcessorType exportProcessorType, string scheme = "http")
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs
index b4b2917491b..c2fdc81eb2e 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExportProtocolParserTests.cs
@@ -8,7 +8,9 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests;
public class OtlpExportProtocolParserTests
{
[Theory]
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData("grpc", true, OtlpExportProtocol.Grpc)]
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[InlineData("http/protobuf", true, OtlpExportProtocol.HttpProtobuf)]
[InlineData("unsupported", false, default(OtlpExportProtocol))]
public void TryParse_Protocol_MapsToCorrectValue(string protocol, bool expectedResult, OtlpExportProtocol expectedExportProtocol)
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterHelperExtensionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterHelperExtensionsTests.cs
new file mode 100644
index 00000000000..4dcd98eb22d
--- /dev/null
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterHelperExtensionsTests.cs
@@ -0,0 +1,138 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if NET462_OR_GREATER || NETSTANDARD2_0
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
+using System.Net.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+using Xunit;
+
+namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests;
+
+public class OtlpExporterHelperExtensionsTests
+{
+ [Fact]
+ public void OtlpExporter_Throws_OnGrpcWithDefaultFactory_ForTracing()
+ {
+ var services = new ServiceCollection();
+ services.AddOpenTelemetry()
+ .WithTracing(tracing => tracing.AddOtlpExporter(options => options.Protocol = OtlpExportProtocol.Grpc));
+
+ using var sp = services.BuildServiceProvider();
+
+ Assert.Throws(() => sp.GetRequiredService());
+
+ var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
+ .AddOtlpExporter(o => o.Protocol = OtlpExportProtocol.Grpc);
+
+ Assert.Throws(() => tracerProviderBuilder.Build());
+ }
+
+ [Fact]
+ public void OtlpExporter_Throws_OnGrpcWithDefaultFactory_ForMetrics()
+ {
+ var services = new ServiceCollection();
+
+ services.AddOpenTelemetry()
+ .WithMetrics(metrics => metrics.AddOtlpExporter(options => options.Protocol = OtlpExportProtocol.Grpc));
+
+ using var sp = services.BuildServiceProvider();
+
+ Assert.Throws(() => sp.GetRequiredService());
+
+ var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
+ .AddOtlpExporter(o => o.Protocol = OtlpExportProtocol.Grpc);
+
+ Assert.Throws(() => meterProviderBuilder.Build());
+ }
+
+ [Fact]
+ public void OtlpExporter_Throws_OnGrpcWithDefaultFactory_ForLogging()
+ {
+ var services = new ServiceCollection();
+
+ services.AddOpenTelemetry()
+ .WithLogging(builder => builder.AddOtlpExporter(options => options.Protocol = OtlpExportProtocol.Grpc));
+
+ using var sp = services.BuildServiceProvider();
+
+ Assert.Throws(() => sp.GetRequiredService());
+
+ Assert.Throws(() => LoggerFactory.Create(builder =>
+ {
+ builder.AddOpenTelemetry(logging =>
+ {
+ logging.AddOtlpExporter(o => o.Protocol = OtlpExportProtocol.Grpc);
+ });
+ }));
+ }
+
+ [Fact]
+ public void OtlpExporter_DoesNotThrow_WhenCustomHttpClientFactoryIsSet_ForTraces()
+ {
+ var services = new ServiceCollection();
+
+ services.AddOpenTelemetry()
+ .WithTracing(builder =>
+ {
+ builder.AddOtlpExporter(options =>
+ {
+ options.Protocol = OtlpExportProtocol.Grpc;
+ options.HttpClientFactory = () => new HttpClient();
+ });
+ });
+
+ using var sp = services.BuildServiceProvider();
+
+ var tracerProvider = sp.GetRequiredService();
+ Assert.NotNull(tracerProvider);
+ }
+
+ [Fact]
+ public void OtlpExporter_DoesNotThrow_WhenCustomHttpClientFactoryIsSet_ForMetrics()
+ {
+ var services = new ServiceCollection();
+
+ services.AddOpenTelemetry()
+ .WithMetrics(builder =>
+ {
+ builder.AddOtlpExporter(options =>
+ {
+ options.Protocol = OtlpExportProtocol.Grpc;
+ options.HttpClientFactory = () => new HttpClient();
+ });
+ });
+
+ using var sp = services.BuildServiceProvider();
+
+ var meterProvider = sp.GetRequiredService();
+ Assert.NotNull(meterProvider);
+ }
+
+ [Fact]
+ public void OtlpExporter_DoesNotThrow_WhenCustomHttpClientFactoryIsSet_ForLogging()
+ {
+ var services = new ServiceCollection();
+
+ services.AddOpenTelemetry()
+ .WithLogging(builder =>
+ {
+ builder.AddOtlpExporter(options =>
+ {
+ options.Protocol = OtlpExportProtocol.Grpc;
+ options.HttpClientFactory = () => new HttpClient();
+ });
+ });
+
+ using var sp = services.BuildServiceProvider();
+
+ var loggerProvider = sp.GetRequiredService();
+ Assert.NotNull(loggerProvider);
+ }
+}
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
+#endif
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs
index 00696f57b0c..f1e3a5fd5fa 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs
@@ -61,11 +61,9 @@ public void GetHeaders_ValidAndUrlEncodedHeaders_ReturnsCorrectHeaders(string in
}
[Theory]
-#if NET462_OR_GREATER
- [InlineData(OtlpExportProtocol.Grpc, typeof(GrpcExportClient))]
-#else
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient))]
-#endif
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient))]
public void GetTraceExportClient_SupportedProtocol_ReturnsCorrectExportClient(OtlpExportProtocol protocol, Type expectedExportClientType)
{
@@ -105,15 +103,11 @@ public void AppendPathIfNotPresent_TracesPath_AppendsCorrectly(string inputUri,
}
[Theory]
-#if NET462_OR_GREATER
- [InlineData(OtlpExportProtocol.Grpc, typeof(GrpcExportClient), false, 10000, null)]
- [InlineData(OtlpExportProtocol.Grpc, typeof(GrpcExportClient), false, 10000, "in_memory")]
- [InlineData(OtlpExportProtocol.Grpc, typeof(GrpcExportClient), false, 10000, "disk")]
-#else
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, null)]
[InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, "in_memory")]
[InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, "disk")]
-#endif
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000, null)]
[InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), true, 8000, null)]
[InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000, "in_memory")]
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
index c22f0e14863..b0fcee2f48d 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs
@@ -24,7 +24,12 @@ public void OtlpExporterOptions_Defaults()
{
var options = new OtlpExporterOptions();
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint);
+#else
Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint);
+#endif
+
Assert.Null(options.Headers);
Assert.Equal(10000, options.TimeoutMilliseconds);
Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol);
@@ -95,7 +100,12 @@ public void OtlpExporterOptions_InvalidEnvironmentVariableOverride()
"NoopHeaders",
"TimeoutWithInvalidValue");
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint);
+#else
Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint);
+#endif
+
Assert.Equal(10000, options.TimeoutMilliseconds);
Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol);
Assert.Null(options.Headers);
@@ -143,14 +153,20 @@ public void OtlpExporterOptions_EndpointGetterUsesProtocolWhenNull()
{
var options = new OtlpExporterOptions();
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint);
+#else
Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint);
+#endif
+
Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, options.Protocol);
options.Protocol = OtlpExportProtocol.HttpProtobuf;
Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), options.Endpoint);
-
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
options.Protocol = OtlpExportProtocol.Grpc;
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), options.Endpoint);
}
@@ -158,10 +174,12 @@ public void OtlpExporterOptions_EndpointGetterUsesProtocolWhenNull()
[Fact]
public void OtlpExporterOptions_EndpointThrowsWhenSetToNull()
{
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
var options = new OtlpExporterOptions { Endpoint = new Uri("http://test:8888"), Protocol = OtlpExportProtocol.Grpc };
Assert.Equal(new Uri("http://test:8888"), options.Endpoint);
Assert.Equal(OtlpExportProtocol.Grpc, options.Protocol);
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
}
[Fact]
@@ -210,7 +228,9 @@ public void OtlpExporterOptions_ApplyDefaultsTest()
var targetOptionsWithData = new OtlpExporterOptions
{
Endpoint = new Uri("http://metrics_endpoint/"),
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
Protocol = OtlpExportProtocol.Grpc,
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
Headers = "key2=value2",
TimeoutMilliseconds = 1800,
HttpClientFactory = () => throw new NotImplementedException(),
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs
index 467ed6c0c25..67160d2c3fd 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/UseOtlpExporterExtensionTests.cs
@@ -38,7 +38,12 @@ public void UseOtlpExporterDefaultTest()
var exporterOptions = sp.GetRequiredService>().CurrentValue;
+#if NET462_OR_GREATER || NETSTANDARD2_0
+ Assert.Equal(new Uri(OtlpExporterOptions.DefaultHttpEndpoint), exporterOptions.DefaultOptions.Endpoint);
+#else
Assert.Equal(new Uri(OtlpExporterOptions.DefaultGrpcEndpoint), exporterOptions.DefaultOptions.Endpoint);
+#endif
+
Assert.Equal(OtlpExporterOptions.DefaultOtlpExportProtocol, exporterOptions.DefaultOptions.Protocol);
Assert.False(((OtlpExporterOptions)exporterOptions.DefaultOptions).HasData);
@@ -48,7 +53,9 @@ public void UseOtlpExporterDefaultTest()
}
[Theory]
+#pragma warning disable CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.Grpc)]
+#pragma warning restore CS0618 // Suppressing gRPC obsolete warning
[InlineData(OtlpExportProtocol.HttpProtobuf)]
public void UseOtlpExporterSetEndpointAndProtocolTest(OtlpExportProtocol protocol)
{