Add HTTP/Protobuf exporter for OTLP Logs (#3225)
This commit is contained in:
parent
06d623bf5a
commit
d1ec45ce15
|
|
@ -169,6 +169,9 @@ namespace Examples.Console
|
||||||
{
|
{
|
||||||
[Option("useExporter", Default = "otlp", HelpText = "Options include otlp or console.", Required = false)]
|
[Option("useExporter", Default = "otlp", HelpText = "Options include otlp or console.", Required = false)]
|
||||||
public string UseExporter { get; set; }
|
public string UseExporter { get; set; }
|
||||||
|
|
||||||
|
[Option('p', "protocol", HelpText = "Transport protocol used by OTLP exporter. Supported values: grpc and http/protobuf. Only applicable if Exporter is OTLP", Default = "grpc")]
|
||||||
|
public string Protocol { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Verb("inmemory", HelpText = "Specify the options required to test InMemory Exporter")]
|
[Verb("inmemory", HelpText = "Specify the options required to test InMemory Exporter")]
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@ namespace Examples.Console
|
||||||
* launch the OpenTelemetry Collector with an OTLP receiver, by running:
|
* launch the OpenTelemetry Collector with an OTLP receiver, by running:
|
||||||
*
|
*
|
||||||
* - On Unix based systems use:
|
* - On Unix based systems use:
|
||||||
* docker run --rm -it -p 4317:4317 -v $(pwd):/cfg otel/opentelemetry-collector:0.33.0 --config=/cfg/otlp-collector-example/config.yaml
|
* docker run --rm -it -p 4317:4317 -p 4318:4318 -v $(pwd):/cfg otel/opentelemetry-collector:0.48.0 --config=/cfg/otlp-collector-example/config.yaml
|
||||||
*
|
*
|
||||||
* - On Windows use:
|
* - On Windows use:
|
||||||
* docker run --rm -it -p 4317:4317 -v "%cd%":/cfg otel/opentelemetry-collector:0.33.0 --config=/cfg/otlp-collector-example/config.yaml
|
* docker run --rm -it -p 4317:4317 -p 4318:4318 -v "%cd%":/cfg otel/opentelemetry-collector:0.48.0 --config=/cfg/otlp-collector-example/config.yaml
|
||||||
*
|
*
|
||||||
* Open another terminal window at the examples/Console/ directory and
|
* Open another terminal window at the examples/Console/ directory and
|
||||||
* launch the OTLP example by running:
|
* launch the OTLP example by running:
|
||||||
|
|
@ -59,7 +59,28 @@ namespace Examples.Console
|
||||||
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
|
// 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);
|
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||||
|
|
||||||
opt.AddOtlpExporter();
|
if (options.Protocol.Trim().ToLower().Equals("grpc"))
|
||||||
|
{
|
||||||
|
opt.AddOtlpExporter(otlpOptions =>
|
||||||
|
{
|
||||||
|
otlpOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (options.Protocol.Trim().ToLower().Equals("http/protobuf"))
|
||||||
|
{
|
||||||
|
opt.AddOtlpExporter(otlpOptions =>
|
||||||
|
{
|
||||||
|
otlpOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.Console.WriteLine($"Export protocol {options.Protocol} is not supported. Default protocol 'grpc' will be used.");
|
||||||
|
opt.AddOtlpExporter(otlpOptions =>
|
||||||
|
{
|
||||||
|
otlpOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
* LogExporter to support Logging Scopes.
|
* LogExporter to support Logging Scopes.
|
||||||
([#3277](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3217))
|
([#3277](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3217))
|
||||||
|
|
||||||
|
* Support `HttpProtobuf` protocol with logs & added `HttpClientFactory`
|
||||||
|
option
|
||||||
|
([#3224](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3224))
|
||||||
|
|
||||||
## 1.3.0-beta.1
|
## 1.3.0-beta.1
|
||||||
|
|
||||||
Released 2022-Apr-15
|
Released 2022-Apr-15
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ using OtlpCollector = Opentelemetry.Proto.Collector.Logs.V1;
|
||||||
|
|
||||||
namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient
|
namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient
|
||||||
{
|
{
|
||||||
/// <summary>Class for sending OTLP metrics export request over gRPC.</summary>
|
/// <summary>Class for sending OTLP Logs export request over gRPC.</summary>
|
||||||
internal sealed class OtlpGrpcLogExportClient : BaseOtlpGrpcExportClient<OtlpCollector.ExportLogsServiceRequest>
|
internal sealed class OtlpGrpcLogExportClient : BaseOtlpGrpcExportClient<OtlpCollector.ExportLogsServiceRequest>
|
||||||
{
|
{
|
||||||
private readonly OtlpCollector.LogsService.LogsServiceClient logsClient;
|
private readonly OtlpCollector.LogsService.LogsServiceClient logsClient;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
// <copyright file="OtlpHttpLogExportClient.cs" company="OpenTelemetry Authors">
|
||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
using System.Threading;
|
||||||
|
#endif
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using OtlpCollector = Opentelemetry.Proto.Collector.Logs.V1;
|
||||||
|
|
||||||
|
namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient
|
||||||
|
{
|
||||||
|
/// <summary>Class for sending OTLP log export request over HTTP.</summary>
|
||||||
|
internal sealed class OtlpHttpLogExportClient : BaseOtlpHttpExportClient<OtlpCollector.ExportLogsServiceRequest>
|
||||||
|
{
|
||||||
|
internal const string MediaContentType = "application/x-protobuf";
|
||||||
|
private const string LogsExportPath = "v1/logs";
|
||||||
|
|
||||||
|
public OtlpHttpLogExportClient(OtlpExporterOptions options, HttpClient httpClient)
|
||||||
|
: base(options, httpClient, LogsExportPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override HttpContent CreateHttpContent(OtlpCollector.ExportLogsServiceRequest exportRequest)
|
||||||
|
{
|
||||||
|
return new ExportRequestContent(exportRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class ExportRequestContent : HttpContent
|
||||||
|
{
|
||||||
|
private static readonly MediaTypeHeaderValue ProtobufMediaTypeHeader = new(MediaContentType);
|
||||||
|
|
||||||
|
private readonly OtlpCollector.ExportLogsServiceRequest exportRequest;
|
||||||
|
|
||||||
|
public ExportRequestContent(OtlpCollector.ExportLogsServiceRequest exportRequest)
|
||||||
|
{
|
||||||
|
this.exportRequest = exportRequest;
|
||||||
|
this.Headers.ContentType = ProtobufMediaTypeHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
protected override void SerializeToStream(Stream stream, TransportContext context, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
this.SerializeToStreamInternal(stream);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
||||||
|
{
|
||||||
|
this.SerializeToStreamInternal(stream);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryComputeLength(out long length)
|
||||||
|
{
|
||||||
|
// We can't know the length of the content being pushed to the output stream.
|
||||||
|
length = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void SerializeToStreamInternal(Stream stream)
|
||||||
|
{
|
||||||
|
this.exportRequest.WriteTo(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
|
||||||
#if NETSTANDARD2_1 || NET5_0_OR_GREATER
|
#if NETSTANDARD2_1 || NET5_0_OR_GREATER
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
#endif
|
#endif
|
||||||
|
using LogOtlpCollector = Opentelemetry.Proto.Collector.Logs.V1;
|
||||||
using MetricsOtlpCollector = Opentelemetry.Proto.Collector.Metrics.V1;
|
using MetricsOtlpCollector = Opentelemetry.Proto.Collector.Metrics.V1;
|
||||||
using TraceOtlpCollector = Opentelemetry.Proto.Collector.Trace.V1;
|
using TraceOtlpCollector = Opentelemetry.Proto.Collector.Trace.V1;
|
||||||
|
|
||||||
|
|
@ -110,6 +111,16 @@ namespace OpenTelemetry.Exporter
|
||||||
_ => throw new NotSupportedException($"Protocol {options.Protocol} is not supported."),
|
_ => throw new NotSupportedException($"Protocol {options.Protocol} is not supported."),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static IExportClient<LogOtlpCollector.ExportLogsServiceRequest> GetLogExportClient(this OtlpExporterOptions options) =>
|
||||||
|
options.Protocol switch
|
||||||
|
{
|
||||||
|
OtlpExportProtocol.Grpc => new OtlpGrpcLogExportClient(options),
|
||||||
|
OtlpExportProtocol.HttpProtobuf => new OtlpHttpLogExportClient(
|
||||||
|
options,
|
||||||
|
options.HttpClientFactory?.Invoke() ?? throw new InvalidOperationException("OtlpExporterOptions was missing HttpClientFactory or it returned null.")),
|
||||||
|
_ => throw new NotSupportedException($"Protocol {options.Protocol} is not supported."),
|
||||||
|
};
|
||||||
|
|
||||||
public static OtlpExportProtocol? ToOtlpExportProtocol(this string protocol) =>
|
public static OtlpExportProtocol? ToOtlpExportProtocol(this string protocol) =>
|
||||||
protocol.Trim() switch
|
protocol.Trim() switch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,7 @@ namespace OpenTelemetry.Exporter
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: this instantiation should be aligned with the protocol option (grpc or http/protobuf) when OtlpHttpMetricsExportClient will be implemented.
|
this.exportClient = options.GetLogExportClient();
|
||||||
this.exportClient = new OtlpGrpcLogExportClient(options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue