OTLP exporter: use Grpc.Net.Client for netstandard2.1 (#1662)

* Use Grpc.Net.Client for netstandard2.1

* Fix AspNetCore example app

* Better comment for Http2UnencryptedSupport switch

* Update PublicAPI

* Update changelog

* Fix line endings

* Suppress instrumentation on export

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
This commit is contained in:
Alan West 2021-01-04 11:45:21 -08:00 committed by GitHub
parent 5e161a993f
commit 4e4f95bb53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 89 additions and 11 deletions

View File

@ -28,7 +28,6 @@
<GoogleProtobufPkgVer>[3.13.0,4.0)</GoogleProtobufPkgVer>
<GrpcAspNetCorePkgVer>[2.27.0,3.0)</GrpcAspNetCorePkgVer>
<GrpcAspNetCoreServerPkgVer>[2.30.0, 3.0)</GrpcAspNetCoreServerPkgVer>
<GrpcNetClientPkgVer>[2.32.0,3.0)</GrpcNetClientPkgVer>
<GrpcToolsPkgVer>[2.25.0,3.0)</GrpcToolsPkgVer>
<MicrosoftAspNetMvcPkgVer>[5.2.7,6.0)</MicrosoftAspNetMvcPkgVer>
<MicrosoftAspNetWebApiWebHostPkgVer>[5.2.7,6.0)</MicrosoftAspNetWebApiWebHostPkgVer>

View File

@ -24,6 +24,7 @@
<MinVerPkgVer>[2.3.0,3.0)</MinVerPkgVer>
<GoogleProtobufPkgVer>[3.6.1,4.0)</GoogleProtobufPkgVer>
<GrpcPkgVer>[2.23.0,3.0)</GrpcPkgVer>
<GrpcNetClientPkgVer>[2.32.0,3.0)</GrpcNetClientPkgVer>
<GrpcToolsPkgVer>[2.25.0,3.0)</GrpcToolsPkgVer>
<MicrosoftAspNetCoreHttpAbstractionsPkgVer>[2.1.1,6.0)</MicrosoftAspNetCoreHttpAbstractionsPkgVer>
<MicrosoftAspNetCoreHttpFeaturesPkgVer>[2.1.1,6.0)</MicrosoftAspNetCoreHttpFeaturesPkgVer>

View File

@ -80,13 +80,18 @@ namespace Examples.AspNetCore
}));
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<string>("Otlp:ServiceName")))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = this.Configuration.GetValue<string>("Otlp:Endpoint");
otlpOptions.Endpoint = new Uri(this.Configuration.GetValue<string>("Otlp:Endpoint"));
}));
break;
default:

View File

@ -133,7 +133,7 @@ namespace Examples.Console
[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; }
}

View File

@ -14,6 +14,7 @@
// limitations under the License.
// </copyright>
using System;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
@ -53,12 +54,17 @@ namespace Examples.Console
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

View File

@ -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<System.Diagnostics.Activity>
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<System.Diagnostics.Activity> activityBatch) -> OpenTelemetry.ExportResult
override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool
static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions> configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder

View File

@ -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

View File

@ -1,14 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452;net46;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net452;net46;netstandard2.0;netstandard2.1</TargetFrameworks>
<Description>OpenTelemetry protocol exporter for OpenTelemetry .NET</Description>
<PackageTags>$(PackageTags);OTLP</PackageTags>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="Grpc.Net.Client" Version="$(GrpcNetClientPkgVer)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.1'">
<PackageReference Include="Grpc" Version="$(GrpcPkgVer)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj" />
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPkgVer)" />
<PackageReference Include="Grpc" Version="$(GrpcPkgVer)" />
<PackageReference Include="Grpc.Tools" Version="$(GrpcToolsPkgVer)" PrivateAssets="all" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />

View File

@ -20,6 +20,9 @@ using System.Diagnostics;
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 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
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 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
}
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 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
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);

View File

@ -14,9 +14,13 @@
// limitations under the License.
// </copyright>
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,27 +29,42 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol
/// </summary>
public class OtlpExporterOptions
{
#if NETSTANDARD2_1
/// <summary>
/// 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.
/// </summary>
public Uri Endpoint { get; set; } = new Uri("http://localhost:55680");
#else
/// <summary>
/// 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.
/// </summary>
public string Endpoint { get; set; } = "localhost:55680";
#endif
#if NETSTANDARD2_1
/// <summary>
/// Gets or sets the gRPC channel options.
/// </summary>
public GrpcChannelOptions GrpcChannelOptions { get; set; }
#else
/// <summary>
/// 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.
/// </summary>
public ChannelCredentials Credentials { get; set; } = ChannelCredentials.Insecure;
/// <summary>
/// Gets or sets optional headers for the connection.
/// </summary>
public Metadata Headers { get; set; } = new Metadata();
/// <summary>
/// Gets or sets the gRPC channel options.
/// </summary>
public IEnumerable<ChannelOption> ChannelOptions { get; set; }
#endif
/// <summary>
/// Gets or sets optional headers for the connection.
/// </summary>
public Metadata Headers { get; set; } = new Metadata();
/// <summary>
/// Gets or sets the export processor type to be used with the OpenTelemetry Protocol Exporter.