From 11c692abcba27a6191113d834d0cf77300eb1f47 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 13:44:15 -0800 Subject: [PATCH 01/13] Add retries to gRPC OTLP Exporter --- .../OtlpExporterOptions.cs | 29 ++++++ .../OtlpExporterOptionsExtensions.cs | 36 +++++++- .../MockCollectorIntegrationTests.cs | 91 +++++++++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 2bf0f7e980f..f275e15d5b4 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -179,6 +179,35 @@ public Uri Endpoint /// public Func HttpClientFactory { get; set; } + /// + /// Gets or sets the maximum number of call attempts. This value + /// includes the original attempt. Used to set + /// Grpc.Net.Client.Configuration.RetryPolicy.MaxAttempts. + /// + /// + /// Setting this value to less than 2 will disable retry attempts. + /// + public int RetryMaxAttempts { get; set; } = 5; + + /// + /// Gets or sets the initial backoff. Used to set + /// Grpc.Net.Client.Configuration.RetryPolicy.InitialBackoff. + /// + public TimeSpan RetryInitialBackoff { get; set; } = TimeSpan.FromSeconds(1); + + /// + /// Gets or sets the maximum backoff. Used to set + /// Grpc.Net.Client.Configuration.RetryPolicy.MaxBackoff. + /// + public TimeSpan RetryMaxBackoff { get; set; } = TimeSpan.FromSeconds(5); + + /// + /// Gets or sets the backoff multiplier. The backoff will be multiplied + /// by RetryBackoffMultiplier after each retry attempt. Used to + /// set Grpc.Net.Client.Configuration.RetryPolicy.BackoffMultiplier. + /// + public double RetryBackoffMultiplier { get; set; } = 1.5; + /// /// Gets a value indicating whether was modified via its setter. /// diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index f118f63c1f9..f1f7a3a6d7d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -21,6 +21,7 @@ using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient; #if NETSTANDARD2_1 || NET6_0_OR_GREATER using Grpc.Net.Client; +using Grpc.Net.Client.Configuration; #endif using LogOtlpCollector = OpenTelemetry.Proto.Collector.Logs.V1; using MetricsOtlpCollector = OpenTelemetry.Proto.Collector.Metrics.V1; @@ -42,7 +43,40 @@ public static Channel CreateChannel(this OtlpExporterOptions options) } #if NETSTANDARD2_1 || NET6_0_OR_GREATER - return GrpcChannel.ForAddress(options.Endpoint); + if (options.RetryMaxAttempts <= 1) { + return GrpcChannel.ForAddress(options.Endpoint); + } + + var retryPolicy = new RetryPolicy + { + MaxAttempts = options.RetryMaxAttempts, + InitialBackoff = options.RetryInitialBackoff, + MaxBackoff = options.RetryMaxBackoff, + BackoffMultiplier = options.RetryBackoffMultiplier, + + RetryableStatusCodes = + { + StatusCode.Cancelled, + StatusCode.DeadlineExceeded, + StatusCode.ResourceExhausted, // TODO: Investigate this one. + StatusCode.Aborted, + StatusCode.OutOfRange, + StatusCode.Unavailable, + StatusCode.DataLoss, + }, + }; + + var methodConfig = new MethodConfig + { + Names = { MethodName.Default }, + RetryPolicy = retryPolicy, + }; + + var serviceConfig = new ServiceConfig { MethodConfigs = { methodConfig } }; + + var channelOptions = new GrpcChannelOptions { ServiceConfig = serviceConfig }; + + return GrpcChannel.ForAddress(options.Endpoint, channelOptions); #else ChannelCredentials channelCredentials; if (options.Endpoint.Scheme == Uri.UriSchemeHttps) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs index 3a0dd6303a5..937f1ef3d6d 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs @@ -108,6 +108,97 @@ public async Task TestRecoveryAfterFailedExport() await host.StopAsync().ConfigureAwait(false); } + [Theory] + [InlineData(1, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled })] + [InlineData(1, ExportResult.Success, new[] { Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DeadlineExceeded, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.ResourceExhausted, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Aborted, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OutOfRange, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Unavailable, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.OK })] + + public async Task TestOtlpExporterRetry(int maxAttempts, ExportResult result, Grpc.Core.StatusCode[] codes) + { + using var host = await new HostBuilder() + .ConfigureWebHostDefaults(webBuilder => webBuilder + .ConfigureKestrel(options => + { + options.ListenLocalhost(5050, listenOptions => listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1); + options.ListenLocalhost(4317, listenOptions => listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2); + }) + .ConfigureServices(services => + { + services.AddSingleton(new MockCollectorState()); + services.AddGrpc(); + }) + .Configure(app => + { + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet( + "/MockCollector/SetResponseCodes/{responseCodesCsv}", + (MockCollectorState collectorState, string responseCodesCsv) => + { + var codes = responseCodesCsv.Split(",").Select(x => int.Parse(x)).ToArray(); + collectorState.SetStatusCodes(codes); + }); + + endpoints.MapGrpcService(); + }); + })) + .StartAsync(); + + var httpClient = new HttpClient() { BaseAddress = new System.Uri("http://localhost:5050") }; + await httpClient.GetAsync($"/MockCollector/SetResponseCodes/{string.Join(",", codes.Select(x => (int)x))}"); + + var exportResults = new List(); + var otlpExporter = new OtlpTraceExporter(new OtlpExporterOptions() + { + Endpoint = new System.Uri("http://localhost:4317"), + RetryMaxAttempts = maxAttempts, + }); + var delegatingExporter = new DelegatingExporter + { + OnExportFunc = (batch) => + { + var result = otlpExporter.Export(batch); + exportResults.Add(result); + return result; + }, + }; + + var activitySourceName = "otel.mock.collector.test"; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(activitySourceName) + .AddProcessor(new SimpleActivityExportProcessor(delegatingExporter)) + .Build(); + + using var source = new ActivitySource(activitySourceName); + + source.StartActivity().Stop(); + + Assert.Single(exportResults); + Assert.Equal(result, exportResults[0]); + + await host.StopAsync().ConfigureAwait(false); + } + private class MockCollectorState { private Grpc.Core.StatusCode[] statusCodes = { }; From c68b911a13d84af3217ecc6a16cf32a295525532 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 13:54:36 -0800 Subject: [PATCH 02/13] formatting --- .../OtlpExporterOptionsExtensions.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index f1f7a3a6d7d..4a6afd6de22 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -43,7 +43,8 @@ public static Channel CreateChannel(this OtlpExporterOptions options) } #if NETSTANDARD2_1 || NET6_0_OR_GREATER - if (options.RetryMaxAttempts <= 1) { + if (options.RetryMaxAttempts <= 1) + { return GrpcChannel.ForAddress(options.Endpoint); } @@ -53,7 +54,7 @@ public static Channel CreateChannel(this OtlpExporterOptions options) InitialBackoff = options.RetryInitialBackoff, MaxBackoff = options.RetryMaxBackoff, BackoffMultiplier = options.RetryBackoffMultiplier, - + RetryableStatusCodes = { StatusCode.Cancelled, From 7930415ab5cd3d813d24cfbf3cd6a61a3ad0dd1e Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 13:54:44 -0800 Subject: [PATCH 03/13] Add publicApi for net6.0 --- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt index d54151c394a..866d022b5ad 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,3 +1,11 @@ +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.get -> int +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.get -> System.Timespan +OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.get -> System.Timespan +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.get -> double +OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.set -> void static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder *REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder From 70e5f2a93130fac6987a8f642c609d3eb7192e1e Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 14:18:28 -0800 Subject: [PATCH 04/13] Update CHANGELOG.md --- src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index e65a0286438..462931c01f1 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -7,6 +7,9 @@ scopes. ([3843](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3843)) +* Add ability to retry failed exports to the gRPC version of the exporter. + ([#xxx](https://github.com/open-telemetry/opentelemetry-dotnet/pull/xxx)) + ## 1.4.0-beta.2 Released 2022-Oct-17 From b27938aac205abad4053bdfb87baba8f86cbd941 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 14:21:35 -0800 Subject: [PATCH 05/13] Update OtlpExporterOptionsExtensions.cs --- .../OtlpExporterOptionsExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 4a6afd6de22..79fd90480c1 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -55,6 +55,8 @@ public static Channel CreateChannel(this OtlpExporterOptions options) MaxBackoff = options.RetryMaxBackoff, BackoffMultiplier = options.RetryBackoffMultiplier, + // See table showing gRPC codes and if they are retryable: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#failures RetryableStatusCodes = { StatusCode.Cancelled, From 1b3e3eda682dd6bbb4d66c07bc9b01463c52c2c9 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 15:00:41 -0800 Subject: [PATCH 06/13] Remove final OK status This is not needed since the mock server will automatically respond with OK if all the provided codes list have been exhausted --- .../MockCollectorIntegrationTests.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs index 937f1ef3d6d..423f9ec2712 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs @@ -71,7 +71,7 @@ public async Task TestRecoveryAfterFailedExport() var httpClient = new HttpClient() { BaseAddress = new System.Uri("http://localhost:5050") }; - var codes = new[] { Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.OK }; + var codes = new[] { Grpc.Core.StatusCode.Unimplemented }; await httpClient.GetAsync($"/MockCollector/SetResponseCodes/{string.Join(",", codes.Select(x => (int)x))}"); var exportResults = new List(); @@ -110,25 +110,25 @@ public async Task TestRecoveryAfterFailedExport() [Theory] [InlineData(1, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled })] - [InlineData(1, ExportResult.Success, new[] { Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DeadlineExceeded, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.ResourceExhausted, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Aborted, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OutOfRange, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Unavailable, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss, Grpc.Core.StatusCode.OK })] + [InlineData(1, ExportResult.Success, new Grpc.Core.StatusCode[] { })] + [InlineData(2, ExportResult.Success, new Grpc.Core.StatusCode[] { })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Cancelled })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DeadlineExceeded })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.ResourceExhausted })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Aborted })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OutOfRange })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Unavailable })] + [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss })] [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.OK })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.OK })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal })] + [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated })] public async Task TestOtlpExporterRetry(int maxAttempts, ExportResult result, Grpc.Core.StatusCode[] codes) { From 6dc5fd864af1b6cdff52fcb06f39b75b280d85d2 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 15:25:31 -0800 Subject: [PATCH 07/13] Update CHANGELOG.md --- src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 462931c01f1..2289b9a12f5 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -8,7 +8,7 @@ ([3843](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3843)) * Add ability to retry failed exports to the gRPC version of the exporter. - ([#xxx](https://github.com/open-telemetry/opentelemetry-dotnet/pull/xxx)) + ([#3883](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3883)) ## 1.4.0-beta.2 From cef6d453271d6230e62b1244f8802edf76aee470 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 9 Nov 2022 15:25:36 -0800 Subject: [PATCH 08/13] Update PublicAPI.Unshipped.txt --- .../.publicApi/netstandard2.1/PublicAPI.Unshipped.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index d54151c394a..866d022b5ad 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,3 +1,11 @@ +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.get -> int +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.get -> System.Timespan +OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.get -> System.Timespan +OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.get -> double +OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.set -> void static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder *REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder From 35ffea6894bf5949ea10672dd5da3bf88c62c7d3 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 16 Nov 2022 13:30:21 -0800 Subject: [PATCH 09/13] Hide options --- .../OtlpExporterOptions.cs | 29 ------------ .../OtlpExporterOptionsExtensions.cs | 18 ++++---- .../MockCollectorIntegrationTests.cs | 44 +++++++++---------- 3 files changed, 30 insertions(+), 61 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index f275e15d5b4..2bf0f7e980f 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -179,35 +179,6 @@ public Uri Endpoint /// public Func HttpClientFactory { get; set; } - /// - /// Gets or sets the maximum number of call attempts. This value - /// includes the original attempt. Used to set - /// Grpc.Net.Client.Configuration.RetryPolicy.MaxAttempts. - /// - /// - /// Setting this value to less than 2 will disable retry attempts. - /// - public int RetryMaxAttempts { get; set; } = 5; - - /// - /// Gets or sets the initial backoff. Used to set - /// Grpc.Net.Client.Configuration.RetryPolicy.InitialBackoff. - /// - public TimeSpan RetryInitialBackoff { get; set; } = TimeSpan.FromSeconds(1); - - /// - /// Gets or sets the maximum backoff. Used to set - /// Grpc.Net.Client.Configuration.RetryPolicy.MaxBackoff. - /// - public TimeSpan RetryMaxBackoff { get; set; } = TimeSpan.FromSeconds(5); - - /// - /// Gets or sets the backoff multiplier. The backoff will be multiplied - /// by RetryBackoffMultiplier after each retry attempt. Used to - /// set Grpc.Net.Client.Configuration.RetryPolicy.BackoffMultiplier. - /// - public double RetryBackoffMultiplier { get; set; } = 1.5; - /// /// Gets a value indicating whether was modified via its setter. /// diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 79fd90480c1..3d0e68170fe 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -31,6 +31,11 @@ namespace OpenTelemetry.Exporter { internal static class OtlpExporterOptionsExtensions { + private const int RetryMaxAttempts = 5; + private const double RetryBackoffMultiplier = 1.5; + private static readonly TimeSpan RetryInitialBackoff = TimeSpan.FromSeconds(1); + private static readonly TimeSpan RetryMaxBackoff = TimeSpan.FromSeconds(5); + #if NETSTANDARD2_1 || NET6_0_OR_GREATER public static GrpcChannel CreateChannel(this OtlpExporterOptions options) #else @@ -43,17 +48,12 @@ public static Channel CreateChannel(this OtlpExporterOptions options) } #if NETSTANDARD2_1 || NET6_0_OR_GREATER - if (options.RetryMaxAttempts <= 1) - { - return GrpcChannel.ForAddress(options.Endpoint); - } - var retryPolicy = new RetryPolicy { - MaxAttempts = options.RetryMaxAttempts, - InitialBackoff = options.RetryInitialBackoff, - MaxBackoff = options.RetryMaxBackoff, - BackoffMultiplier = options.RetryBackoffMultiplier, + MaxAttempts = RetryMaxAttempts, + InitialBackoff = RetryInitialBackoff, + MaxBackoff = RetryMaxBackoff, + BackoffMultiplier = RetryBackoffMultiplier, // See table showing gRPC codes and if they are retryable: // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#failures diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs index 423f9ec2712..821cbc38254 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs @@ -109,28 +109,27 @@ public async Task TestRecoveryAfterFailedExport() } [Theory] - [InlineData(1, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled })] - [InlineData(1, ExportResult.Success, new Grpc.Core.StatusCode[] { })] - [InlineData(2, ExportResult.Success, new Grpc.Core.StatusCode[] { })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Cancelled })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DeadlineExceeded })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.ResourceExhausted })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Aborted })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.OutOfRange })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.Unavailable })] - [InlineData(2, ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal })] - [InlineData(2, ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated })] - - public async Task TestOtlpExporterRetry(int maxAttempts, ExportResult result, Grpc.Core.StatusCode[] codes) + [InlineData(ExportResult.Success, new Grpc.Core.StatusCode[] { })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.Cancelled })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.DeadlineExceeded })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.ResourceExhausted })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.Aborted })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.OutOfRange })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.Unavailable })] + [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss })] + + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated })] + + public async Task TestOtlpExporterRetry(ExportResult result, Grpc.Core.StatusCode[] codes) { using var host = await new HostBuilder() .ConfigureWebHostDefaults(webBuilder => webBuilder @@ -170,7 +169,6 @@ public async Task TestOtlpExporterRetry(int maxAttempts, ExportResult result, Gr var otlpExporter = new OtlpTraceExporter(new OtlpExporterOptions() { Endpoint = new System.Uri("http://localhost:4317"), - RetryMaxAttempts = maxAttempts, }); var delegatingExporter = new DelegatingExporter { From 611e3ec2846ee777041eabf605c5d752be0deeca Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 16 Nov 2022 13:49:17 -0800 Subject: [PATCH 10/13] Remove publicApi changes --- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 8 -------- .../.publicApi/netstandard2.1/PublicAPI.Unshipped.txt | 8 -------- 2 files changed, 16 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt index 866d022b5ad..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,11 +1,3 @@ -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.get -> int -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.get -> System.Timespan -OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.get -> System.Timespan -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.get -> double -OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.set -> void static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder *REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 866d022b5ad..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,11 +1,3 @@ -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.get -> int -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxAttempts.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.get -> System.Timespan -OpenTelemetry.Exporter.OtlpExporterOptions.RetryInitialBackoff.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.get -> System.Timespan -OpenTelemetry.Exporter.OtlpExporterOptions.RetryMaxBackoff.set -> void -OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.get -> double -OpenTelemetry.Exporter.OtlpExporterOptions.RetryBackoffMultiplier.set -> void static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder *REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder From 9a487ab7e3a0a50d6bcd764e6e0cb83a7b343803 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 16 Nov 2022 18:23:23 -0800 Subject: [PATCH 11/13] ci rerun From daff9b0489495fb47a64cc42c65baaa321f4d9f0 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 17 Nov 2022 12:04:13 -0800 Subject: [PATCH 12/13] Fix tests --- .../MockCollectorIntegrationTests.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs index 821cbc38254..fb9ce578de1 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/MockCollectorIntegrationTests.cs @@ -119,15 +119,16 @@ public async Task TestRecoveryAfterFailedExport() [InlineData(ExportResult.Success, new[] { Grpc.Core.StatusCode.DataLoss })] [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled, Grpc.Core.StatusCode.Cancelled })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown, Grpc.Core.StatusCode.Unknown })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument, Grpc.Core.StatusCode.InvalidArgument })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound, Grpc.Core.StatusCode.NotFound })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists, Grpc.Core.StatusCode.AlreadyExists })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied, Grpc.Core.StatusCode.PermissionDenied })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition, Grpc.Core.StatusCode.FailedPrecondition })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented, Grpc.Core.StatusCode.Unimplemented })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.Internal })] - [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated, Grpc.Core.StatusCode.Unauthenticated })] + + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unknown })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.InvalidArgument })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.NotFound })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.AlreadyExists })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.PermissionDenied })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.FailedPrecondition })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unimplemented })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Internal })] + [InlineData(ExportResult.Failure, new[] { Grpc.Core.StatusCode.Unauthenticated })] public async Task TestOtlpExporterRetry(ExportResult result, Grpc.Core.StatusCode[] codes) { From a5fac986fc7cc59de2441da25ec3560effea3146 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Fri, 18 Nov 2022 12:15:16 -0800 Subject: [PATCH 13/13] ci rerun