diff --git a/.changelog/5143.added b/.changelog/5143.added new file mode 100644 index 00000000000..04588c17c07 --- /dev/null +++ b/.changelog/5143.added @@ -0,0 +1 @@ +`opentelemetry-exporter-otlp-proto-grpc`: Add grpc error details to the log message that's written when the grpc call fails. \ No newline at end of file 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 5b79a9574bd..60d26683695 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 @@ -512,10 +512,11 @@ def _export( or self._shutdown ): logger.error( - "Failed to export %s to %s, error code: %s", + "Failed to export %s to %s, error code: %s, error details: %s", self._exporting, self._endpoint, error.code(), # type: ignore [reportAttributeAccessIssue] + error.details(), exc_info=error.code() == StatusCode.UNKNOWN, # type: ignore [reportAttributeAccessIssue] ) result.error = error @@ -524,11 +525,12 @@ def _export( } return self._result.FAILURE # type: ignore [reportReturnType] logger.warning( - "Transient error %s encountered while exporting %s to %s, retrying in %.2fs.", + "Transient error %s encountered while exporting %s to %s, retrying in %.2fs. Error details: %s", error.code(), # type: ignore [reportAttributeAccessIssue] self._exporting, self._endpoint, backoff_seconds, + error.details(), ) shutdown = self._shutdown_in_progress.wait(backoff_seconds) if shutdown: diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py index 91749fa16f5..50996264a09 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py @@ -109,11 +109,13 @@ def __init__( export_result: StatusCode, optional_retry_nanos: int | None = None, optional_export_sleep: float | None = None, + optional_error_details: str | None = None, ): self.export_result = export_result self.optional_export_sleep = optional_export_sleep self.optional_retry_nanos = optional_retry_nanos self.num_requests = 0 + self.optional_error_details = optional_error_details # pylint: disable=invalid-name,unused-argument def Export(self, request, context): @@ -134,6 +136,8 @@ def Export(self, request, context): ) ) context.set_code(self.export_result) + if self.optional_error_details: + context.set_details(self.optional_error_details) return ExportTraceServiceResponse() @@ -599,7 +603,7 @@ def test_timeout_set_correctly(self): ) after = time.time() self.assertEqual( - "Failed to export traces to localhost:4317, error code: StatusCode.DEADLINE_EXCEEDED", + "Failed to export traces to localhost:4317, error code: StatusCode.DEADLINE_EXCEEDED, error details: Deadline Exceeded", warning.records[-1].message, ) self.assertEqual(mock_trace_service.num_requests, 2) @@ -633,7 +637,8 @@ def test_permanent_failure(self): with self.assertLogs(level=WARNING) as warning: add_TraceServiceServicer_to_server( TraceServiceServicerWithExportParams( - StatusCode.ALREADY_EXISTS + StatusCode.ALREADY_EXISTS, + optional_error_details="This already exists.", ), self.server, ) @@ -642,7 +647,7 @@ def test_permanent_failure(self): ) self.assertEqual( warning.records[-1].message, - "Failed to export traces to localhost:4317, error code: StatusCode.ALREADY_EXISTS", + "Failed to export traces to localhost:4317, error code: StatusCode.ALREADY_EXISTS, error details: This already exists.", ) metrics_data = self.metric_reader.get_metrics_data()