From 89a5729b34fa43fe53a91337cb4972ad3d52f37c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 16 Feb 2024 11:24:56 -0800 Subject: [PATCH 01/12] Introduce transmission handler --- .../OtlpExporterTransmissionHandler.cs | 108 ++++++++++++++++++ .../OtlpExporterOptionsExtensions.cs | 10 ++ .../OtlpLogExporter.cs | 23 ++-- .../OtlpMetricExporter.cs | 25 ++-- .../OtlpTraceExporter.cs | 39 +++---- .../Exporter/OtlpGrpcExporterBenchmarks.cs | 4 +- .../Exporter/OtlpHttpExporterBenchmarks.cs | 4 +- .../OtlpLogExporterTests.cs | 105 ++--------------- .../OtlpTraceExporterTests.cs | 5 +- 9 files changed, 166 insertions(+), 157 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs new file mode 100644 index 00000000000..7a1a55bb5e7 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -0,0 +1,108 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; + +internal class OtlpExporterTransmissionHandler +{ + public OtlpExporterTransmissionHandler(IExportClient exportClient) + { + Guard.ThrowIfNull(exportClient); + + this.ExportClient = exportClient; + } + + protected IExportClient ExportClient { get; } + + /// + /// Sends export request to the server. + /// + /// The request to send to the server. + /// True if the request is sent successfully or else false. + public bool SubmitRequest(TRequest request) + { + try + { + var response = this.ExportClient.SendExportRequest(request); + if (response.Success) + { + return true; + } + + return this.OnSubmitRequestFailure(request, response); + } + catch (Exception ex) + { + OpenTelemetryProtocolExporterEventSource.Log.ExportMethodException(ex); + this.OnRequestDropped(request); + return false; + } + } + + /// + /// Attempts to shutdown the transmission handler, blocks the current thread + /// until shutdown completed or timed out. + /// + /// + /// The number (non-negative) of milliseconds to wait, or + /// Timeout.Infinite to wait indefinitely. + /// + /// + /// Returns if shutdown succeeded; otherwise, . + /// + public bool Shutdown(int timeoutMilliseconds) + { + this.OnShutdown(); + + return this.ExportClient.Shutdown(timeoutMilliseconds); + } + + /// + /// Fired when the transmission handler is shutdown. + /// + protected virtual void OnShutdown() + { + } + + /// + /// Fired when a request could not be submitted. + /// + /// The request that was attempted to send to the server. + /// . + /// if the request will be resubmitted. + protected virtual bool OnSubmitRequestFailure(TRequest request, ExportClientResponse response) + { + this.OnRequestDropped(request); + return false; + } + + /// + /// Fired when a request could not be submitted. + /// + /// The request that was attempted to send to the server. + /// . + protected ExportClientResponse RetryRequest(TRequest request) + { + var response = this.ExportClient.SendExportRequest(request); + if (!response.Success) + { + OpenTelemetryProtocolExporterEventSource.Log.ExportMethodException(response.Exception, isRetry: true); + } + + return response; + } + + /// + /// Fired when a request is dropped. + /// + /// The request that was attempted to send to the server. + protected virtual void OnRequestDropped(TRequest request) + { + } +} diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 91a23749804..44133af1f84 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -10,6 +10,7 @@ #if NETSTANDARD2_1 || NET6_0_OR_GREATER using Grpc.Net.Client; #endif +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using LogOtlpCollector = OpenTelemetry.Proto.Collector.Logs.V1; using MetricsOtlpCollector = OpenTelemetry.Proto.Collector.Metrics.V1; using TraceOtlpCollector = OpenTelemetry.Proto.Collector.Trace.V1; @@ -87,6 +88,15 @@ public static THeaders GetHeaders(this OtlpExporterOptions options, Ac return headers; } + public static OtlpExporterTransmissionHandler GetTraceExportTransmissionHandler(this OtlpExporterOptions options) + => new(GetTraceExportClient(options)); + + public static OtlpExporterTransmissionHandler GetMetricsExportTransmissionHandler(this OtlpExporterOptions options) + => new(GetMetricsExportClient(options)); + + public static OtlpExporterTransmissionHandler GetLogsExportTransmissionHandler(this OtlpExporterOptions options) + => new(GetLogExportClient(options)); + public static IExportClient GetTraceExportClient(this OtlpExporterOptions options) => options.Protocol switch { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs index 7ee6bf74f3c..9734f054a99 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs @@ -5,7 +5,7 @@ using System.Diagnostics; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; -using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Internal; using OpenTelemetry.Logs; using OtlpCollector = OpenTelemetry.Proto.Collector.Logs.V1; @@ -19,7 +19,7 @@ namespace OpenTelemetry.Exporter; /// public sealed class OtlpLogExporter : BaseExporter { - private readonly IExportClient exportClient; + private readonly OtlpExporterTransmissionHandler transmissionHandler; private readonly OtlpLogRecordTransformer otlpLogRecordTransformer; private OtlpResource.Resource? processResource; @@ -29,7 +29,7 @@ public sealed class OtlpLogExporter : BaseExporter /// /// Configuration options for the exporter. public OtlpLogExporter(OtlpExporterOptions options) - : this(options, sdkLimitOptions: new(), experimentalOptions: new(), exportClient: null) + : this(options, sdkLimitOptions: new(), experimentalOptions: new(), transmissionHandler: null) { } @@ -39,12 +39,12 @@ public OtlpLogExporter(OtlpExporterOptions options) /// Configuration options for the exporter. /// . /// . - /// Client used for sending export request. + /// . internal OtlpLogExporter( OtlpExporterOptions exporterOptions, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, - IExportClient? exportClient = null) + OtlpExporterTransmissionHandler? transmissionHandler = null) { Debug.Assert(exporterOptions != null, "exporterOptions was null"); Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null"); @@ -62,14 +62,7 @@ internal OtlpLogExporter( OpenTelemetryProtocolExporterEventSource.Log.InvalidEnvironmentVariable(key, value); }; - if (exportClient != null) - { - this.exportClient = exportClient; - } - else - { - this.exportClient = exporterOptions!.GetLogExportClient(); - } + this.transmissionHandler = transmissionHandler ?? exporterOptions.GetLogsExportTransmissionHandler(); this.otlpLogRecordTransformer = new OtlpLogRecordTransformer(sdkLimitOptions!, experimentalOptions!); } @@ -89,7 +82,7 @@ public override ExportResult Export(in Batch logRecordBatch) { request = this.otlpLogRecordTransformer.BuildExportRequest(this.ProcessResource, logRecordBatch); - if (!this.exportClient.SendExportRequest(request).Success) + if (!this.transmissionHandler.SubmitRequest(request)) { return ExportResult.Failure; } @@ -113,6 +106,6 @@ public override ExportResult Export(in Batch logRecordBatch) /// protected override bool OnShutdown(int timeoutMilliseconds) { - return this.exportClient?.Shutdown(timeoutMilliseconds) ?? true; + return this.transmissionHandler?.Shutdown(timeoutMilliseconds) ?? true; } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs index ecc97994166..98e033bfdaa 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; -using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; using OtlpCollector = OpenTelemetry.Proto.Collector.Metrics.V1; @@ -16,7 +16,7 @@ namespace OpenTelemetry.Exporter; /// public class OtlpMetricExporter : BaseExporter { - private readonly IExportClient exportClient; + private readonly OtlpExporterTransmissionHandler transmissionHandler; private OtlpResource.Resource processResource; @@ -25,7 +25,7 @@ public class OtlpMetricExporter : BaseExporter /// /// Configuration options for the exporter. public OtlpMetricExporter(OtlpExporterOptions options) - : this(options, null) + : this(options, transmissionHandler: null) { } @@ -33,8 +33,10 @@ public OtlpMetricExporter(OtlpExporterOptions options) /// Initializes a new instance of the class. /// /// Configuration options for the export. - /// Client used for sending export request. - internal OtlpMetricExporter(OtlpExporterOptions options, IExportClient exportClient = null) + /// . + internal OtlpMetricExporter( + OtlpExporterOptions options, + OtlpExporterTransmissionHandler transmissionHandler = null) { // Each of the Otlp exporters: Traces, Metrics, and Logs set the same value for `OtlpKeyValueTransformer.LogUnsupportedAttributeType` // and `ConfigurationExtensions.LogInvalidEnvironmentVariable` so it should be fine even if these exporters are used together. @@ -48,14 +50,7 @@ internal OtlpMetricExporter(OtlpExporterOptions options, IExportClient this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource(); @@ -72,7 +67,7 @@ public override ExportResult Export(in Batch metrics) { request.AddMetrics(this.ProcessResource, metrics); - if (!this.exportClient.SendExportRequest(request).Success) + if (!this.transmissionHandler.SubmitRequest(request)) { return ExportResult.Failure; } @@ -93,6 +88,6 @@ public override ExportResult Export(in Batch metrics) /// protected override bool OnShutdown(int timeoutMilliseconds) { - return this.exportClient?.Shutdown(timeoutMilliseconds) ?? true; + return this.transmissionHandler.Shutdown(timeoutMilliseconds); } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index 5febb7f4d01..e0644e19876 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; -using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Internal; using OtlpCollector = OpenTelemetry.Proto.Collector.Trace.V1; using OtlpResource = OpenTelemetry.Proto.Resource.V1; @@ -17,7 +17,7 @@ namespace OpenTelemetry.Exporter; public class OtlpTraceExporter : BaseExporter { private readonly SdkLimitOptions sdkLimitOptions; - private readonly IExportClient exportClient; + private readonly OtlpExporterTransmissionHandler transmissionHandler; private OtlpResource.Resource processResource; @@ -26,7 +26,7 @@ public class OtlpTraceExporter : BaseExporter /// /// Configuration options for the export. public OtlpTraceExporter(OtlpExporterOptions options) - : this(options, new(), null) + : this(options, sdkLimitOptions: new()) { } @@ -35,35 +35,22 @@ public OtlpTraceExporter(OtlpExporterOptions options) /// /// . /// . - /// Client used for sending export request. + /// . internal OtlpTraceExporter( - OtlpExporterOptions exporterOptions, - SdkLimitOptions sdkLimitOptions, - IExportClient exportClient = null) + OtlpExporterOptions exporterOptions, + SdkLimitOptions sdkLimitOptions, + OtlpExporterTransmissionHandler transmissionHandler = null) { Debug.Assert(exporterOptions != null, "exporterOptions was null"); Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null"); - this.sdkLimitOptions = sdkLimitOptions; + this.sdkLimitOptions = sdkLimitOptions!; - OtlpKeyValueTransformer.LogUnsupportedAttributeType = (string tagValueType, string tagKey) => - { - OpenTelemetryProtocolExporterEventSource.Log.UnsupportedAttributeType(tagValueType, tagKey); - }; + OtlpKeyValueTransformer.LogUnsupportedAttributeType = OpenTelemetryProtocolExporterEventSource.Log.UnsupportedAttributeType; - ConfigurationExtensions.LogInvalidEnvironmentVariable = (string key, string value) => - { - OpenTelemetryProtocolExporterEventSource.Log.InvalidEnvironmentVariable(key, value); - }; + ConfigurationExtensions.LogInvalidEnvironmentVariable = OpenTelemetryProtocolExporterEventSource.Log.InvalidEnvironmentVariable; - if (exportClient != null) - { - this.exportClient = exportClient; - } - else - { - this.exportClient = exporterOptions.GetTraceExportClient(); - } + this.transmissionHandler = transmissionHandler ?? exporterOptions.GetTraceExportTransmissionHandler(); } internal OtlpResource.Resource ProcessResource => this.processResource ??= this.ParentProvider.GetResource().ToOtlpResource(); @@ -80,7 +67,7 @@ public override ExportResult Export(in Batch activityBatch) { request.AddBatch(this.sdkLimitOptions, this.ProcessResource, activityBatch); - if (!this.exportClient.SendExportRequest(request).Success) + if (!this.transmissionHandler.SubmitRequest(request)) { return ExportResult.Failure; } @@ -101,6 +88,6 @@ public override ExportResult Export(in Batch activityBatch) /// protected override bool OnShutdown(int timeoutMilliseconds) { - return this.exportClient?.Shutdown(timeoutMilliseconds) ?? true; + return this.transmissionHandler.Shutdown(timeoutMilliseconds); } } diff --git a/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs index b8cffdbdb71..f80d59d2a14 100644 --- a/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpGrpcExporterBenchmarks.cs @@ -11,6 +11,8 @@ using OpenTelemetryProtocol::OpenTelemetry.Exporter; using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; +using OpenTelemetryProtocol::OpenTelemetry.Proto.Collector.Trace.V1; namespace Benchmarks.Exporter; @@ -33,7 +35,7 @@ public void GlobalSetup() this.exporter = new OtlpTraceExporter( options, new SdkLimitOptions(), - new OtlpGrpcTraceExportClient(options, new TestTraceServiceClient())); + new OtlpExporterTransmissionHandler(new OtlpGrpcTraceExportClient(options, new TestTraceServiceClient()))); this.activity = ActivityHelper.CreateTestActivity(); this.activityBatch = new CircularBuffer(this.NumberOfSpans); diff --git a/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs index d4560579a92..86e79812be0 100644 --- a/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpHttpExporterBenchmarks.cs @@ -12,6 +12,8 @@ using OpenTelemetryProtocol::OpenTelemetry.Exporter; using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; +using OpenTelemetryProtocol::OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; +using OpenTelemetryProtocol::OpenTelemetry.Proto.Collector.Trace.V1; namespace Benchmarks.Exporter; @@ -61,7 +63,7 @@ public void GlobalSetup() this.exporter = new OtlpTraceExporter( options, new SdkLimitOptions(), - new OtlpHttpTraceExportClient(options, options.HttpClientFactory())); + new OtlpExporterTransmissionHandler(new OtlpHttpTraceExportClient(options, options.HttpClientFactory()))); this.activity = ActivityHelper.CreateTestActivity(); this.activityBatch = new CircularBuffer(this.NumberOfSpans); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index 7181557ae5a..5def91db71b 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Internal; using OpenTelemetry.Logs; using OpenTelemetry.Resources; @@ -589,63 +590,6 @@ public void CheckToOtlpLogRecordBodyIsPopulated(bool includeFormattedMessage) Assert.Equal("state", otlpLogRecord.Body.StringValue); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void LogRecordBodyIsExportedWhenUsingBridgeApi(bool isBodySet) - { - LogRecordAttributeList attributes = default; - attributes.Add("name", "tomato"); - attributes.Add("price", 2.99); - attributes.Add("{OriginalFormat}", "Hello from {name} {price}."); - - var logRecords = new List(); - - using (var loggerProvider = Sdk.CreateLoggerProviderBuilder() - .AddInMemoryExporter(logRecords) - .Build()) - { - var logger = loggerProvider.GetLogger(); - - logger.EmitLog(new LogRecordData() - { - Body = isBodySet ? "Hello world" : null, - }); - - logger.EmitLog(new LogRecordData(), attributes); - } - - Assert.Equal(2, logRecords.Count); - - var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); - - var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[0]); - - if (isBodySet) - { - Assert.Equal("Hello world", otlpLogRecord.Body?.StringValue); - } - else - { - Assert.Null(otlpLogRecord.Body); - } - - otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[1]); - - Assert.Equal(2, otlpLogRecord.Attributes.Count); - - var index = 0; - var attribute = otlpLogRecord.Attributes[index]; - Assert.Equal("name", attribute.Key); - Assert.Equal("tomato", attribute.Value.StringValue); - - attribute = otlpLogRecord.Attributes[++index]; - Assert.Equal("price", attribute.Key); - Assert.Equal(2.99, attribute.Value.DoubleValue); - - Assert.Equal("Hello from {name} {price}.", otlpLogRecord.Body.StringValue); - } - [Fact] public void CheckToOtlpLogRecordExceptionAttributes() { @@ -731,13 +675,14 @@ public void Export_WhenExportClientIsProvidedInCtor_UsesProvidedExportClient() { // Arrange. var testExportClient = new TestExportClient(); + var transmissionHandler = new OtlpExporterTransmissionHandler(testExportClient); var emptyLogRecords = Array.Empty(); var emptyBatch = new Batch(emptyLogRecords, emptyLogRecords.Length); var sut = new OtlpLogExporter( new OtlpExporterOptions(), new SdkLimitOptions(), new ExperimentalOptions(), - testExportClient); + transmissionHandler); // Act. sut.Export(emptyBatch); @@ -751,13 +696,14 @@ public void Export_WhenExportClientThrowsException_ReturnsExportResultFailure() { // Arrange. var testExportClient = new TestExportClient(throwException: true); + var transmissionHandler = new OtlpExporterTransmissionHandler(testExportClient); var emptyLogRecords = Array.Empty(); var emptyBatch = new Batch(emptyLogRecords, emptyLogRecords.Length); var sut = new OtlpLogExporter( new OtlpExporterOptions(), new SdkLimitOptions(), new ExperimentalOptions(), - testExportClient); + transmissionHandler); // Act. var result = sut.Export(emptyBatch); @@ -771,13 +717,14 @@ public void Export_WhenExportIsSuccessful_ReturnsExportResultSuccess() { // Arrange. var testExportClient = new TestExportClient(); + var transmissionHandler = new OtlpExporterTransmissionHandler(testExportClient); var emptyLogRecords = Array.Empty(); var emptyBatch = new Batch(emptyLogRecords, emptyLogRecords.Length); var sut = new OtlpLogExporter( new OtlpExporterOptions(), new SdkLimitOptions(), new ExperimentalOptions(), - testExportClient); + transmissionHandler); // Act. var result = sut.Export(emptyBatch); @@ -1469,44 +1416,6 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBui }); } - [Theory] - [InlineData("my_instrumentation_scope_name", "my_instrumentation_scope_name")] - [InlineData(null, "")] - public void LogRecordLoggerNameIsExportedWhenUsingBridgeApi(string loggerName, string expectedScopeName) - { - LogRecordAttributeList attributes = default; - attributes.Add("name", "tomato"); - attributes.Add("price", 2.99); - attributes.Add("{OriginalFormat}", "Hello from {name} {price}."); - - var logRecords = new List(); - - using (var loggerProvider = Sdk.CreateLoggerProviderBuilder() - .AddInMemoryExporter(logRecords) - .Build()) - { - var logger = loggerProvider.GetLogger(loggerName); - - logger.EmitLog(new LogRecordData()); - } - - Assert.Single(logRecords); - - var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); - - var batch = new Batch(new[] { logRecords[0] }, 1); - - var request = otlpLogRecordTransformer.BuildExportRequest( - new Proto.Resource.V1.Resource(), - batch); - - Assert.NotNull(request); - Assert.Single(request.ResourceLogs); - Assert.Single(request.ResourceLogs[0].ScopeLogs); - - Assert.Equal(expectedScopeName, request.ResourceLogs[0].ScopeLogs[0].Scope?.Name); - } - private static void RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( string optionsName, Func, (IDisposable Container, ILoggerFactory LoggerFactory)> createLoggerFactoryFunc) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 95f61d41297..0c7a5db76e2 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -5,6 +5,7 @@ using Google.Protobuf.Collections; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation; +using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.Transmission; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Tests; @@ -629,7 +630,9 @@ public void Shutdown_ClientShutdownIsCalled() { var exportClientMock = new TestExportClient(); - var exporter = new OtlpTraceExporter(new OtlpExporterOptions(), DefaultSdkLimitOptions, exportClientMock); + var transmissionHandler = new OtlpExporterTransmissionHandler(exportClientMock); + + var exporter = new OtlpTraceExporter(new OtlpExporterOptions(), DefaultSdkLimitOptions, transmissionHandler); exporter.Shutdown(); From f8042f6031235557c6e394f283f67133ac8eeb00 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 16 Feb 2024 11:31:35 -0800 Subject: [PATCH 02/12] add back test --- .../OtlpLogExporterTests.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index 5def91db71b..cd34bd8c03b 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -1416,6 +1416,44 @@ public void VerifyEnvironmentVariablesTakenFromIConfigurationWhenUsingLoggingBui }); } + [Theory] + [InlineData("my_instrumentation_scope_name", "my_instrumentation_scope_name")] + [InlineData(null, "")] + public void LogRecordLoggerNameIsExportedWhenUsingBridgeApi(string loggerName, string expectedScopeName) + { + LogRecordAttributeList attributes = default; + attributes.Add("name", "tomato"); + attributes.Add("price", 2.99); + attributes.Add("{OriginalFormat}", "Hello from {name} {price}."); + + var logRecords = new List(); + + using (var loggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(logRecords) + .Build()) + { + var logger = loggerProvider.GetLogger(loggerName); + + logger.EmitLog(new LogRecordData()); + } + + Assert.Single(logRecords); + + var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); + + var batch = new Batch(new[] { logRecords[0] }, 1); + + var request = otlpLogRecordTransformer.BuildExportRequest( + new Proto.Resource.V1.Resource(), + batch); + + Assert.NotNull(request); + Assert.Single(request.ResourceLogs); + Assert.Single(request.ResourceLogs[0].ScopeLogs); + + Assert.Equal(expectedScopeName, request.ResourceLogs[0].ScopeLogs[0].Scope?.Name); + } + private static void RunVerifyEnvironmentVariablesTakenFromIConfigurationTest( string optionsName, Func, (IDisposable Container, ILoggerFactory LoggerFactory)> createLoggerFactoryFunc) From 450ef43c26de1be03d280084e8099748589dd5c5 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 16 Feb 2024 11:35:00 -0800 Subject: [PATCH 03/12] revert --- .../OtlpTraceExporter.cs | 2 +- .../OtlpLogExporterTests.cs | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index e0644e19876..7c3cdba7914 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -44,7 +44,7 @@ internal OtlpTraceExporter( Debug.Assert(exporterOptions != null, "exporterOptions was null"); Debug.Assert(sdkLimitOptions != null, "sdkLimitOptions was null"); - this.sdkLimitOptions = sdkLimitOptions!; + this.sdkLimitOptions = sdkLimitOptions; OtlpKeyValueTransformer.LogUnsupportedAttributeType = OpenTelemetryProtocolExporterEventSource.Log.UnsupportedAttributeType; diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index cd34bd8c03b..a01d992040b 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -590,6 +590,63 @@ public void CheckToOtlpLogRecordBodyIsPopulated(bool includeFormattedMessage) Assert.Equal("state", otlpLogRecord.Body.StringValue); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void LogRecordBodyIsExportedWhenUsingBridgeApi(bool isBodySet) + { + LogRecordAttributeList attributes = default; + attributes.Add("name", "tomato"); + attributes.Add("price", 2.99); + attributes.Add("{OriginalFormat}", "Hello from {name} {price}."); + + var logRecords = new List(); + + using (var loggerProvider = Sdk.CreateLoggerProviderBuilder() + .AddInMemoryExporter(logRecords) + .Build()) + { + var logger = loggerProvider.GetLogger(); + + logger.EmitLog(new LogRecordData() + { + Body = isBodySet ? "Hello world" : null, + }); + + logger.EmitLog(new LogRecordData(), attributes); + } + + Assert.Equal(2, logRecords.Count); + + var otlpLogRecordTransformer = new OtlpLogRecordTransformer(DefaultSdkLimitOptions, new()); + + var otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[0]); + + if (isBodySet) + { + Assert.Equal("Hello world", otlpLogRecord.Body?.StringValue); + } + else + { + Assert.Null(otlpLogRecord.Body); + } + + otlpLogRecord = otlpLogRecordTransformer.ToOtlpLog(logRecords[1]); + + Assert.Equal(2, otlpLogRecord.Attributes.Count); + + var index = 0; + var attribute = otlpLogRecord.Attributes[index]; + Assert.Equal("name", attribute.Key); + Assert.Equal("tomato", attribute.Value.StringValue); + + attribute = otlpLogRecord.Attributes[++index]; + Assert.Equal("price", attribute.Key); + Assert.Equal(2.99, attribute.Value.DoubleValue); + + Assert.Equal("Hello from {name} {price}.", otlpLogRecord.Body.StringValue); + } + [Fact] public void CheckToOtlpLogRecordExceptionAttributes() { From 52e13a19fd0afd57a2906062684ce066d0fd45aa Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Feb 2024 08:37:52 -0800 Subject: [PATCH 04/12] Update src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .../OtlpTraceExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index 7c3cdba7914..ab7e3665f98 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -26,7 +26,7 @@ public class OtlpTraceExporter : BaseExporter /// /// Configuration options for the export. public OtlpTraceExporter(OtlpExporterOptions options) - : this(options, sdkLimitOptions: new()) + : this(options, sdkLimitOptions: new(), transmissionHandler: null) { } From 1de6f2ff7411af3a3e31748fa6985531cb5fe9b4 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Feb 2024 11:11:05 -0800 Subject: [PATCH 05/12] review --- .../Transmission/OtlpExporterTransmissionHandler.cs | 2 +- .../OtlpLogExporter.cs | 2 +- .../OtlpMetricExporter.cs | 2 +- .../OtlpTraceExporter.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs index 7a1a55bb5e7..1d56b22dbfb 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -24,7 +24,7 @@ public OtlpExporterTransmissionHandler(IExportClient exportClient) /// /// The request to send to the server. /// True if the request is sent successfully or else false. - public bool SubmitRequest(TRequest request) + public bool TrySubmitRequest(TRequest request) { try { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs index 9734f054a99..8e5c626d917 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpLogExporter.cs @@ -82,7 +82,7 @@ public override ExportResult Export(in Batch logRecordBatch) { request = this.otlpLogRecordTransformer.BuildExportRequest(this.ProcessResource, logRecordBatch); - if (!this.transmissionHandler.SubmitRequest(request)) + if (!this.transmissionHandler.TrySubmitRequest(request)) { return ExportResult.Failure; } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs index 98e033bfdaa..a0026d1e9f4 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporter.cs @@ -67,7 +67,7 @@ public override ExportResult Export(in Batch metrics) { request.AddMetrics(this.ProcessResource, metrics); - if (!this.transmissionHandler.SubmitRequest(request)) + if (!this.transmissionHandler.TrySubmitRequest(request)) { return ExportResult.Failure; } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index ab7e3665f98..f017d075428 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -67,7 +67,7 @@ public override ExportResult Export(in Batch activityBatch) { request.AddBatch(this.sdkLimitOptions, this.ProcessResource, activityBatch); - if (!this.transmissionHandler.SubmitRequest(request)) + if (!this.transmissionHandler.TrySubmitRequest(request)) { return ExportResult.Failure; } From 0d08c78bbb18cf9eb658815804d51540cc478ccf Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Feb 2024 11:18:19 -0800 Subject: [PATCH 06/12] add comment follow up --- .../Implementation/ExportClient/BaseOtlpHttpExportClient.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs index 56f0118aa87..8f98447e3b3 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs @@ -38,6 +38,9 @@ protected BaseOtlpHttpExportClient(OtlpExporterOptions options, HttpClient httpC /// public ExportClientResponse SendExportRequest(TRequest request, CancellationToken cancellationToken = default) { + // Using this.HttpClient.Timeout.TotalMilliseconds here as the client can be configured by the user + // in this case the timeout set within the client will take precedence over timeout set via otlpexporter options + // the value will also match the timeout set via options when the client is NOT provided by the user. DateTime deadline = DateTime.UtcNow.AddMilliseconds(this.HttpClient.Timeout.TotalMilliseconds); try { From 9a0e14fcd6a37cf59b2da4fd2542ab2d06c36af0 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Feb 2024 11:24:03 -0800 Subject: [PATCH 07/12] eventsource --- ...OpenTelemetryProtocolExporterEventSource.cs | 18 ++++++++++++++++++ .../OtlpExporterTransmissionHandler.cs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs index 31ed2a749f4..249b423ce38 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs @@ -33,6 +33,15 @@ public void ExportMethodException(Exception ex, bool isRetry = false) } } + [NonEvent] + public void SubmitRequestException(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.SubmitRequestException(ex.ToInvariantString()); + } + } + [Event(2, Message = "Exporter failed send data to collector to {0} endpoint. Data will not be sent. Exception: {1}", Level = EventLevel.Error)] public void FailedToReachCollector(string rawCollectorUri, string ex) { @@ -83,4 +92,13 @@ public void InvalidEnvironmentVariable(string key, string value) { this.WriteEvent(11, key, value); } + +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] +#endif + [Event(12, Message = "Unknown error in TrySubmitRequest method. Message: '{0}'. IsRetry: {1}", Level = EventLevel.Error)] + public void SubmitRequestException(string ex) + { + this.WriteEvent(12, ex); + } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs index 1d56b22dbfb..7a885142628 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -38,7 +38,7 @@ public bool TrySubmitRequest(TRequest request) } catch (Exception ex) { - OpenTelemetryProtocolExporterEventSource.Log.ExportMethodException(ex); + OpenTelemetryProtocolExporterEventSource.Log.SubmitRequestException(ex); this.OnRequestDropped(request); return false; } From 006ca17c73b0f6d08daef0b3472a0b353463cfcc Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Feb 2024 11:33:40 -0800 Subject: [PATCH 08/12] fix --- .../Implementation/OpenTelemetryProtocolExporterEventSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs index 249b423ce38..b23f961242b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs @@ -96,7 +96,7 @@ public void InvalidEnvironmentVariable(string key, string value) #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] #endif - [Event(12, Message = "Unknown error in TrySubmitRequest method. Message: '{0}'. IsRetry: {1}", Level = EventLevel.Error)] + [Event(12, Message = "Unknown error in TrySubmitRequest method. Message: '{0}'", Level = EventLevel.Error)] public void SubmitRequestException(string ex) { this.WriteEvent(12, ex); From abe3c463c3b2f98ee37e96dc1aff84ad2de9e1c8 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 22 Feb 2024 08:54:30 -0800 Subject: [PATCH 09/12] feedback --- .../ExportClient/BaseOtlpHttpExportClient.cs | 6 ++-- ...penTelemetryProtocolExporterEventSource.cs | 6 ++-- .../OtlpExporterTransmissionHandler.cs | 35 ++++++++++++++----- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs index 8f98447e3b3..4aad820b1e2 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/BaseOtlpHttpExportClient.cs @@ -38,9 +38,9 @@ protected BaseOtlpHttpExportClient(OtlpExporterOptions options, HttpClient httpC /// public ExportClientResponse SendExportRequest(TRequest request, CancellationToken cancellationToken = default) { - // Using this.HttpClient.Timeout.TotalMilliseconds here as the client can be configured by the user - // in this case the timeout set within the client will take precedence over timeout set via otlpexporter options - // the value will also match the timeout set via options when the client is NOT provided by the user. + // `HttpClient.Timeout.TotalMilliseconds` would be populated with the correct timeout value for both the exporter configuration cases: + // 1. User provides their own HttpClient. This case is straightforward as the user wants to use their `HttpClient` and thereby the same client's timeout value. + // 2. If the user configures timeout via the exporter options, then the timeout set for the `HttpClient` initialized by the exporter will be set to user provided value. DateTime deadline = DateTime.UtcNow.AddMilliseconds(this.HttpClient.Timeout.TotalMilliseconds); try { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs index b23f961242b..fb1ef472282 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs @@ -34,11 +34,11 @@ public void ExportMethodException(Exception ex, bool isRetry = false) } [NonEvent] - public void SubmitRequestException(Exception ex) + public void TrySubmitRequestException(Exception ex) { if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.SubmitRequestException(ex.ToInvariantString()); + this.TrySubmitRequestException(ex.ToInvariantString()); } } @@ -97,7 +97,7 @@ public void InvalidEnvironmentVariable(string key, string value) [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] #endif [Event(12, Message = "Unknown error in TrySubmitRequest method. Message: '{0}'", Level = EventLevel.Error)] - public void SubmitRequestException(string ex) + public void TrySubmitRequestException(string ex) { this.WriteEvent(12, ex); } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs index 7a885142628..efcbd1d1edf 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -3,6 +3,7 @@ #nullable enable +using System.Diagnostics; using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; using OpenTelemetry.Internal; @@ -20,10 +21,12 @@ public OtlpExporterTransmissionHandler(IExportClient exportClient) protected IExportClient ExportClient { get; } /// - /// Sends export request to the server. + /// Attempts to send an export request to the server. /// /// The request to send to the server. - /// True if the request is sent successfully or else false. + /// if the request is sent successfully; otherwise, . + /// public bool TrySubmitRequest(TRequest request) { try @@ -38,7 +41,7 @@ public bool TrySubmitRequest(TRequest request) } catch (Exception ex) { - OpenTelemetryProtocolExporterEventSource.Log.SubmitRequestException(ex); + OpenTelemetryProtocolExporterEventSource.Log.TrySubmitRequestException(ex); this.OnRequestDropped(request); return false; } @@ -58,7 +61,18 @@ public bool TrySubmitRequest(TRequest request) /// public bool Shutdown(int timeoutMilliseconds) { - this.OnShutdown(); + Guard.ThrowIfInvalidTimeout(timeoutMilliseconds); + + var sw = timeoutMilliseconds == Timeout.Infinite ? null : Stopwatch.StartNew(); + + this.OnShutdown(timeoutMilliseconds); + + if (sw != null) + { + var timeout = timeoutMilliseconds - sw.ElapsedMilliseconds; + + return this.ExportClient.Shutdown((int)Math.Max(timeout, 0)); + } return this.ExportClient.Shutdown(timeoutMilliseconds); } @@ -66,7 +80,11 @@ public bool Shutdown(int timeoutMilliseconds) /// /// Fired when the transmission handler is shutdown. /// - protected virtual void OnShutdown() + /// + /// The number (non-negative) of milliseconds to wait, or + /// Timeout.Infinite to wait indefinitely. + /// + protected virtual void OnShutdown(int timeoutMilliseconds) { } @@ -75,7 +93,8 @@ protected virtual void OnShutdown() /// /// The request that was attempted to send to the server. /// . - /// if the request will be resubmitted. + /// If the request is resubmitted and succeeds; otherwise, . protected virtual bool OnSubmitRequestFailure(TRequest request, ExportClientResponse response) { this.OnRequestDropped(request); @@ -83,9 +102,9 @@ protected virtual bool OnSubmitRequestFailure(TRequest request, ExportClientResp } /// - /// Fired when a request could not be submitted. + /// Fired when resending a request to the server. /// - /// The request that was attempted to send to the server. + /// The request to be resent to the server. /// . protected ExportClientResponse RetryRequest(TRequest request) { From 11b37e3d20e75d4d6de3f4cdf793c25ad390e0d6 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 22 Feb 2024 14:40:47 -0800 Subject: [PATCH 10/12] remove ondropped --- .../Transmission/OtlpExporterTransmissionHandler.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs index efcbd1d1edf..9d964a2ff74 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -42,7 +42,6 @@ public bool TrySubmitRequest(TRequest request) catch (Exception ex) { OpenTelemetryProtocolExporterEventSource.Log.TrySubmitRequestException(ex); - this.OnRequestDropped(request); return false; } } @@ -97,7 +96,6 @@ protected virtual void OnShutdown(int timeoutMilliseconds) /// langword="false" />. protected virtual bool OnSubmitRequestFailure(TRequest request, ExportClientResponse response) { - this.OnRequestDropped(request); return false; } @@ -116,12 +114,4 @@ protected ExportClientResponse RetryRequest(TRequest request) return response; } - - /// - /// Fired when a request is dropped. - /// - /// The request that was attempted to send to the server. - protected virtual void OnRequestDropped(TRequest request) - { - } } From 24804202d76d795c18490639cb0270ed1e1c1398 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 23 Feb 2024 11:07:10 -0800 Subject: [PATCH 11/12] rmv aot suppress --- .../OpenTelemetryProtocolExporterEventSource.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs index fb1ef472282..97fe4dcb80b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OpenTelemetryProtocolExporterEventSource.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -#endif using System.Diagnostics.Tracing; using OpenTelemetry.Internal; @@ -54,9 +51,6 @@ public void CouldNotTranslateActivity(string className, string methodName) this.WriteEvent(3, className, methodName); } -#if NET6_0_OR_GREATER - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] -#endif [Event(4, Message = "Unknown error in export method. Message: '{0}'. IsRetry: {1}", Level = EventLevel.Error)] public void ExportMethodException(string ex, bool isRetry) { @@ -93,9 +87,6 @@ public void InvalidEnvironmentVariable(string key, string value) this.WriteEvent(11, key, value); } -#if NET6_0_OR_GREATER - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] -#endif [Event(12, Message = "Unknown error in TrySubmitRequest method. Message: '{0}'", Level = EventLevel.Error)] public void TrySubmitRequestException(string ex) { From 788fd7f3128ed874227b09c7f69fcd1d083cefdd Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 23 Feb 2024 11:38:10 -0800 Subject: [PATCH 12/12] address feedback --- .../Transmission/OtlpExporterTransmissionHandler.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs index 9d964a2ff74..71f4d5ebac1 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Transmission/OtlpExporterTransmissionHandler.cs @@ -103,15 +103,18 @@ protected virtual bool OnSubmitRequestFailure(TRequest request, ExportClientResp /// Fired when resending a request to the server. /// /// The request to be resent to the server. - /// . - protected ExportClientResponse RetryRequest(TRequest request) + /// . + /// If the retry succeeds; otherwise, . + protected bool TryRetryRequest(TRequest request, out ExportClientResponse response) { - var response = this.ExportClient.SendExportRequest(request); + response = this.ExportClient.SendExportRequest(request); if (!response.Success) { OpenTelemetryProtocolExporterEventSource.Log.ExportMethodException(response.Exception, isRetry: true); + return false; } - return response; + return true; } }