From f399195f25c7c4ff1966efa6ef875eabf5405e37 Mon Sep 17 00:00:00 2001 From: Jacob Davis-Hansson Date: Wed, 22 Nov 2023 19:40:11 +0100 Subject: [PATCH] Add stack trace on `StatusCode.UNKNOWN` export error (#3536) --- CHANGELOG.md | 2 ++ .../exporter/otlp/proto/grpc/exporter.py | 1 + .../tests/test_otlp_metrics_exporter.py | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1ad66ccf..9cc24ba9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Log stacktrace on `UNKNOWN` status OTLP export error + ([#3536](https://github.com/open-telemetry/opentelemetry-python/pull/3536)) - Fix OTLPExporterMixin shutdown timeout period ([#3524](https://github.com/open-telemetry/opentelemetry-python/pull/3524)) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 67188d04a4..b422682828 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -308,6 +308,7 @@ def _export( self._exporting, self._endpoint, error.code(), + exc_info=error.code() == StatusCode.UNKNOWN, ) if error.code() == StatusCode.OK: diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index 1d9d65405c..291e9457ef 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -112,6 +112,14 @@ def Export(self, request, context): return ExportMetricsServiceResponse() +class MetricsServiceServicerUNKNOWN(MetricsServiceServicer): + # pylint: disable=invalid-name,unused-argument,no-self-use + def Export(self, request, context): + context.set_code(StatusCode.UNKNOWN) + + return ExportMetricsServiceResponse() + + class MetricsServiceServicerSUCCESS(MetricsServiceServicer): # pylint: disable=invalid-name,unused-argument,no-self-use def Export(self, request, context): @@ -441,6 +449,31 @@ def test_unavailable_delay(self, mock_sleep, mock_expo): ) mock_sleep.assert_called_with(4) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator" + ) + @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep") + @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.logger.error") + def test_unknown_logs(self, mock_logger_error, mock_sleep, mock_expo): + + mock_expo.configure_mock(**{"return_value": [1]}) + + add_MetricsServiceServicer_to_server( + MetricsServiceServicerUNKNOWN(), self.server + ) + self.assertEqual( + self.exporter.export(self.metrics["sum_int"]), + MetricExportResult.FAILURE, + ) + mock_sleep.assert_not_called() + mock_logger_error.assert_called_with( + "Failed to export %s to %s, error code: %s", + "metrics", + "localhost:4317", + StatusCode.UNKNOWN, + exc_info=True, + ) + def test_success(self): add_MetricsServiceServicer_to_server( MetricsServiceServicerSUCCESS(), self.server