diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props
index 28877f3bb99..7bd7554f769 100644
--- a/build/Common.nonprod.props
+++ b/build/Common.nonprod.props
@@ -28,7 +28,6 @@
[3.13.0,4.0)
[2.27.0,3.0)
[2.30.0, 3.0)
- [2.32.0,3.0)
[2.25.0,3.0)
[5.2.7,6.0)
[5.2.7,6.0)
diff --git a/build/Common.props b/build/Common.props
index b719ee866a5..b00ef806eac 100644
--- a/build/Common.props
+++ b/build/Common.props
@@ -24,6 +24,7 @@
[2.3.0,3.0)
[3.6.1,4.0)
[2.23.0,3.0)
+ [2.32.0,3.0)
[2.25.0,3.0)
[2.1.1,6.0)
[2.1.1,6.0)
diff --git a/examples/AspNetCore/Startup.cs b/examples/AspNetCore/Startup.cs
index 3e12b76c0f0..9711826df8e 100644
--- a/examples/AspNetCore/Startup.cs
+++ b/examples/AspNetCore/Startup.cs
@@ -80,13 +80,18 @@ public void ConfigureServices(IServiceCollection services)
}));
break;
case "otlp":
+ // Adding the OtlpExporter creates a GrpcChannel.
+ // This switch must be set before creating a GrpcChannel/HttpClient 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);
+
services.AddOpenTelemetryTracing((builder) => builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue("Otlp:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(otlpOptions =>
{
- otlpOptions.Endpoint = this.Configuration.GetValue("Otlp:Endpoint");
+ otlpOptions.Endpoint = new Uri(this.Configuration.GetValue("Otlp:Endpoint"));
}));
break;
default:
diff --git a/examples/Console/Program.cs b/examples/Console/Program.cs
index 8248363a6a0..508bf826a97 100644
--- a/examples/Console/Program.cs
+++ b/examples/Console/Program.cs
@@ -133,7 +133,7 @@ internal class OpenTracingShimOptions
[Verb("otlp", HelpText = "Specify the options required to test OpenTelemetry Protocol (OTLP)")]
internal class OtlpOptions
{
- [Option('e', "endpoint", HelpText = "Target to which the exporter is going to send traces or metrics", Default = "localhost:55680")]
+ [Option('e', "endpoint", HelpText = "Target to which the exporter is going to send traces or metrics", Default = "http://localhost:55680")]
public string Endpoint { get; set; }
}
diff --git a/examples/Console/TestOtlpExporter.cs b/examples/Console/TestOtlpExporter.cs
index 8043ca3844b..656e5ba06e2 100644
--- a/examples/Console/TestOtlpExporter.cs
+++ b/examples/Console/TestOtlpExporter.cs
@@ -14,6 +14,7 @@
// limitations under the License.
//
+using System;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
@@ -53,12 +54,17 @@ internal static object Run(string endpoint)
private static object RunWithActivitySource(string endpoint)
{
+ // Adding the OtlpExporter creates a GrpcChannel.
+ // This switch must be set before creating a GrpcChannel/HttpClient 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);
+
// Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient"
// and use OTLP exporter.
using var openTelemetry = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("otlp-test"))
- .AddOtlpExporter(opt => opt.Endpoint = endpoint)
+ .AddOtlpExporter(opt => opt.Endpoint = new Uri(endpoint))
.Build();
// The above line is required only in Applications
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Shipped.txt
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt
new file mode 100644
index 00000000000..846802596aa
--- /dev/null
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt
@@ -0,0 +1,18 @@
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OtlpExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.set -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.GrpcChannelOptions.get -> Grpc.Net.Client.GrpcChannelOptions
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.GrpcChannelOptions.set -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Endpoint.get -> System.Uri
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Endpoint.set -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessorType.get -> OpenTelemetry.ExportProcessorType
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessorType.set -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.get -> Grpc.Core.Metadata
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.set -> void
+OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.OtlpExporterOptions() -> void
+OpenTelemetry.Trace.OtlpExporterHelperExtensions
+override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult
+override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool
+static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
index ec369cc8ee8..1b2ce181932 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
@@ -8,6 +8,13 @@
* In `OtlpExporterOptions.cs`: Exporter options now include a switch for
Batch vs Simple exporter, and settings for batch exporting properties.
+* Introduce a `netstandard2.1` build enabling the exporter to use the
+ [gRPC for .NET](https://github.com/grpc/grpc-dotnet) library instead of the
+ [gRPC for C#](https://github.com/grpc/grpc/tree/master/src/csharp) library
+ for .NET Core 3.0+ applications. This required some breaking changes to the
+ `OtlpExporterOptions`.
+ ([#1662](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1662))
+
## 1.0.0-rc1.1
Released 2020-Nov-17
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
index e265339da42..34067c518fa 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj
@@ -1,14 +1,21 @@
- net452;net46;netstandard2.0
+ net452;net46;netstandard2.0;netstandard2.1
OpenTelemetry protocol exporter for OpenTelemetry .NET
$(PackageTags);OTLP
+
+
+
+
+
+
+
+
-
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs
index e875bf64dca..7352aaf8094 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs
@@ -20,6 +20,9 @@
using System.Linq;
using System.Threading.Tasks;
using Grpc.Core;
+#if NETSTANDARD2_1
+using Grpc.Net.Client;
+#endif
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Resources;
using OtlpCollector = Opentelemetry.Proto.Collector.Trace.V1;
@@ -37,7 +40,11 @@ public class OtlpExporter : BaseExporter
private const string DefaultServiceName = "OpenTelemetry Exporter";
private readonly OtlpExporterOptions options;
+#if NETSTANDARD2_1
+ private readonly GrpcChannel channel;
+#else
private readonly Channel channel;
+#endif
private readonly OtlpCollector.TraceService.ITraceServiceClient traceClient;
private readonly Metadata headers;
@@ -65,7 +72,13 @@ internal OtlpExporter(OtlpExporterOptions options, OtlpCollector.TraceService.IT
}
else
{
+#if NETSTANDARD2_1
+ this.channel = options.GrpcChannelOptions == default
+ ? GrpcChannel.ForAddress(options.Endpoint)
+ : GrpcChannel.ForAddress(options.Endpoint, options.GrpcChannelOptions);
+#else
this.channel = new Channel(options.Endpoint, options.Credentials, options.ChannelOptions);
+#endif
this.traceClient = new OtlpCollector.TraceService.TraceServiceClient(this.channel);
}
}
@@ -80,6 +93,9 @@ public override ExportResult Export(in Batch activityBatch)
this.SetResource(this.ParentProvider.GetResource());
}
+ // Prevents the exporter's gRPC and HTTP operations from being instrumented.
+ using var scope = SuppressInstrumentationScope.Begin();
+
OtlpCollector.ExportTraceServiceRequest request = new OtlpCollector.ExportTraceServiceRequest();
request.AddBatch(this.ProcessResource, activityBatch);
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
index 694fdbd82a7..a0cbdf4ec8c 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs
@@ -14,9 +14,13 @@
// limitations under the License.
//
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using Grpc.Core;
+#if NETSTANDARD2_1
+using Grpc.Net.Client;
+#endif
namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
{
@@ -25,12 +29,26 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
///
public class OtlpExporterOptions
{
+#if NETSTANDARD2_1
+ ///
+ /// Gets or sets the target to which the exporter is going to send traces or metrics.
+ /// The valid syntax is described at https://github.com/grpc/grpc/blob/master/doc/naming.md.
+ ///
+ public Uri Endpoint { get; set; } = new Uri("http://localhost:55680");
+#else
///
/// Gets or sets the target to which the exporter is going to send traces or metrics.
/// The valid syntax is described at https://github.com/grpc/grpc/blob/master/doc/naming.md.
///
public string Endpoint { get; set; } = "localhost:55680";
+#endif
+#if NETSTANDARD2_1
+ ///
+ /// Gets or sets the gRPC channel options.
+ ///
+ public GrpcChannelOptions GrpcChannelOptions { get; set; }
+#else
///
/// Gets or sets the client-side channel credentials. Used for creation of a secure channel.
/// The default is "insecure". See detais at https://grpc.io/docs/guides/auth/#credential-types.
@@ -38,14 +56,15 @@ public class OtlpExporterOptions
public ChannelCredentials Credentials { get; set; } = ChannelCredentials.Insecure;
///
- /// Gets or sets optional headers for the connection.
+ /// Gets or sets the gRPC channel options.
///
- public Metadata Headers { get; set; } = new Metadata();
+ public IEnumerable ChannelOptions { get; set; }
+#endif
///
- /// Gets or sets the gRPC channel options.
+ /// Gets or sets optional headers for the connection.
///
- public IEnumerable ChannelOptions { get; set; }
+ public Metadata Headers { get; set; } = new Metadata();
///
/// Gets or sets the export processor type to be used with the OpenTelemetry Protocol Exporter.