From 871ebd6594fa7207cd7cbccc17cbb3fa55daadfa Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Sun, 19 Jul 2026 12:12:26 -0500 Subject: [PATCH 1/2] Log OTLP partial-success responses across all signals and transports The OTLP gRPC and HTTP exporters never inspected the partial_success field of the export response, so spans, data points or log records rejected by the collector were silently dropped. Both transports now deserialize the export response for traces, metrics and logs and log a warning that includes the rejected count and any error message when a partial success is reported. The export result is unchanged: a partial success is still returned as SUCCESS since the request itself was accepted. --- .changelog/0000.fixed | 4 ++ .../exporter/otlp/proto/grpc/exporter.py | 32 ++++++++++- .../tests/test_otlp_exporter_mixin.py | 53 ++++++++++++++++++- .../otlp/proto/http/_common/__init__.py | 38 +++++++++++++ .../otlp/proto/http/_log_exporter/__init__.py | 7 +++ .../proto/http/metric_exporter/__init__.py | 5 ++ .../proto/http/trace_exporter/__init__.py | 7 +++ .../metrics/test_otlp_metrics_exporter.py | 39 ++++++++++++++ .../tests/test_proto_log_exporter.py | 39 ++++++++++++++ .../tests/test_proto_span_exporter.py | 41 ++++++++++++++ 10 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 .changelog/0000.fixed diff --git a/.changelog/0000.fixed b/.changelog/0000.fixed new file mode 100644 index 0000000000..1b1b9b0760 --- /dev/null +++ b/.changelog/0000.fixed @@ -0,0 +1,4 @@ +OTLP exporters (gRPC and HTTP) now inspect the export response and log a warning +on partial success, reporting the number of rejected spans, data points or log +records and any error message returned by the collector. Previously +collector-rejected telemetry was silently dropped. 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 4735091091..bea8805c0c 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 @@ -150,6 +150,35 @@ } +def _log_partial_success(response) -> None: + """Log a warning if an OTLP export response reports a partial success. + + A partial success is signalled by the collector either rejecting some + items (``rejected_spans`` / ``rejected_data_points`` / ``rejected_log_records`` + != 0) or by returning a non-empty ``error_message``. The request itself was + still accepted, so this only logs; it does not change the export result. + """ + if response is None or not response.HasField("partial_success"): + return + partial_success = response.partial_success + rejected = 0 + for field_name in ( + "rejected_spans", + "rejected_data_points", + "rejected_log_records", + ): + if hasattr(partial_success, field_name): + rejected = getattr(partial_success, field_name) + break + error_message = partial_success.error_message + if rejected != 0 or error_message: + logger.warning( + "Partial success received from collector: %s items rejected. %s", + rejected, + error_message, + ) + + class InvalidCompressionValueException(Exception): def __init__(self, environ_key: str, environ_value: str): super().__init__(f'Invalid value "{environ_value}" for compression envvar {environ_key}') @@ -423,11 +452,12 @@ def _export( try: if self._client is None: return self._result.FAILURE - self._client.Export( + response = self._client.Export( request=self._translate_data(data), metadata=self._headers, timeout=deadline_sec - time(), ) + _log_partial_success(response) return self._result.SUCCESS # type: ignore [reportReturnType] except RpcError as error: retry_info_bin = dict(error.trailing_metadata()).get( # type: ignore [reportAttributeAccessIssue] 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 b874a4c777..16f5400f59 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 @@ -108,12 +108,16 @@ def __init__( optional_retry_nanos: int | None = None, optional_export_sleep: float | None = None, optional_error_details: str | None = None, + optional_rejected_spans: int | None = None, + optional_partial_error_message: 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 + self.optional_rejected_spans = optional_rejected_spans + self.optional_partial_error_message = optional_partial_error_message # pylint: disable=invalid-name,unused-argument def Export(self, request, context): @@ -133,7 +137,16 @@ def Export(self, request, context): if self.optional_error_details: context.set_details(self.optional_error_details) - return ExportTraceServiceResponse() + response = ExportTraceServiceResponse() + if self.optional_rejected_spans is not None: + response.partial_success.rejected_spans = ( + self.optional_rejected_spans + ) + if self.optional_partial_error_message is not None: + response.partial_success.error_message = ( + self.optional_partial_error_message + ) + return response class ThreadWithReturnValue(threading.Thread): @@ -377,6 +390,44 @@ def test_shutdown(self): "Exporter already shutdown, ignoring batch", ) + def test_partial_success_logs_warning(self): + """A partial-success response with rejected spans logs a warning.""" + add_TraceServiceServicer_to_server( + TraceServiceServicerWithExportParams( + StatusCode.OK, + optional_rejected_spans=4, + optional_partial_error_message="some spans were dropped", + ), + self.server, + ) + exporter = OTLPSpanExporterForTesting( + insecure=True, meter_provider=self.meter_provider + ) + with self.assertLogs(level=WARNING) as warning: + self.assertEqual( + exporter.export([self.span]), SpanExportResult.SUCCESS + ) + self.assertIn("4 items rejected", warning.output[0]) + self.assertIn("some spans were dropped", warning.output[0]) + + def test_full_success_logs_nothing(self): + """A fully successful (empty partial_success) response logs nothing.""" + add_TraceServiceServicer_to_server( + TraceServiceServicerWithExportParams(StatusCode.OK), + self.server, + ) + exporter = OTLPSpanExporterForTesting( + insecure=True, meter_provider=self.meter_provider + ) + exporter_logger = getLogger( + "opentelemetry.exporter.otlp.proto.grpc.exporter" + ) + with patch.object(exporter_logger, "warning") as mock_warning: + self.assertEqual( + exporter.export([self.span]), SpanExportResult.SUCCESS + ) + mock_warning.assert_not_called() + @unittest.skipIf( system() == "Windows", "For gRPC + windows there's some added delay in the RPCs which breaks the assertion over amount of time passed.", diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_common/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_common/__init__.py index b5959300df..4eb82fda30 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_common/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_common/__init__.py @@ -1,6 +1,7 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +import logging from os import environ from typing import Literal @@ -11,6 +12,8 @@ ) from opentelemetry.util._importlib_metadata import entry_points +_logger = logging.getLogger(__name__) + # 64 MiB, in bytes. _DEFAULT_MAX_REQUEST_SIZE = 64 * 1024 * 1024 @@ -23,6 +26,41 @@ class RequestPayloadTooLargeError(Exception): """ +def _log_partial_success(response_bytes: bytes, response_class) -> None: + """Deserialize an OTLP export response and log a warning if it reports a + partial success. + + A partial success is signalled by the collector either rejecting some + items (``rejected_spans`` / ``rejected_data_points`` / ``rejected_log_records`` + != 0) or by returning a non-empty ``error_message``. The request itself was + still accepted, so this only logs; it does not change the export result. + """ + try: + response = response_class.FromString(response_bytes) + except Exception: # pylint: disable=broad-except + # An unparseable body must not turn a successful export into a failure. + return + if not response.HasField("partial_success"): + return + partial_success = response.partial_success + rejected = 0 + for field_name in ( + "rejected_spans", + "rejected_data_points", + "rejected_log_records", + ): + if hasattr(partial_success, field_name): + rejected = getattr(partial_success, field_name) + break + error_message = partial_success.error_message + if rejected != 0 or error_message: + _logger.warning( + "Partial success received from collector: %s items rejected. %s", + rejected, + error_message, + ) + + def _is_retryable(resp: requests.Response) -> bool: if resp.status_code == 408: return True diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index c7b1decc96..342a3d6615 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -30,8 +30,12 @@ _is_request_too_large, _is_retryable, _load_session_from_envvar, + _log_partial_success, ) from opentelemetry.metrics import MeterProvider +from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( + ExportLogsServiceResponse, +) from opentelemetry.sdk._logs import ReadableLogRecord from opentelemetry.sdk._logs.export import ( LogRecordExporter, @@ -232,6 +236,9 @@ def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: + _log_partial_success( + resp.content, ExportLogsServiceResponse + ) return LogRecordExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index 32a9326ae4..d071e011ca 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -44,10 +44,12 @@ _is_request_too_large, _is_retryable, _load_session_from_envvar, + _log_partial_success, ) from opentelemetry.metrics import MeterProvider from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( # noqa: F401 ExportMetricsServiceRequest, + ExportMetricsServiceResponse, ) from opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 AnyValue, @@ -288,6 +290,9 @@ def _export_with_retries( try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: + _log_partial_success( + resp.content, ExportMetricsServiceResponse + ) return MetricExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py index 306a13340b..2979a474d9 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py @@ -32,8 +32,12 @@ _is_request_too_large, _is_retryable, _load_session_from_envvar, + _log_partial_success, ) from opentelemetry.metrics import MeterProvider +from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( + ExportTraceServiceResponse, +) from opentelemetry.sdk.environment_variables import ( _OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER, OTEL_EXPORTER_OTLP_CERTIFICATE, @@ -227,6 +231,9 @@ def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: + _log_partial_success( + resp.content, ExportTraceServiceResponse + ) return SpanExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py index 93465bd6b3..0843acf4f9 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # pylint: disable=too-many-lines +import logging import threading import time from logging import WARNING @@ -30,6 +31,7 @@ from opentelemetry.exporter.otlp.proto.http.version import __version__ from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( ExportMetricsServiceRequest, + ExportMetricsServiceResponse, ) from opentelemetry.proto.common.v1.common_pb2 import ( InstrumentationScope, @@ -1241,6 +1243,43 @@ def test_2xx_status_code(self, mock_otlp_metric_exporter): MetricExportResult.SUCCESS, ) + @patch.object(Session, "post") + def test_partial_success_logs_warning(self, mock_post): + """A partial-success response with rejected data points logs a warning.""" + response = ExportMetricsServiceResponse() + response.partial_success.rejected_data_points = 5 + response.partial_success.error_message = "some points were dropped" + resp = Response() + resp.status_code = 200 + resp._content = response.SerializeToString() + mock_post.return_value = resp + + with self.assertLogs(level=WARNING) as warning: + self.assertEqual( + OTLPMetricExporter().export(self.metrics["sum_int"]), + MetricExportResult.SUCCESS, + ) + self.assertIn("5 items rejected", warning.output[0]) + self.assertIn("some points were dropped", warning.output[0]) + + @patch.object(Session, "post") + def test_full_success_logs_nothing(self, mock_post): + """A fully successful (empty partial_success) response logs nothing.""" + resp = Response() + resp.status_code = 200 + resp._content = ExportMetricsServiceResponse().SerializeToString() + mock_post.return_value = resp + + logger = logging.getLogger( + "opentelemetry.exporter.otlp.proto.http._common" + ) + with patch.object(logger, "warning") as mock_warning: + self.assertEqual( + OTLPMetricExporter().export(self.metrics["sum_int"]), + MetricExportResult.SUCCESS, + ) + mock_warning.assert_not_called() + @patch.dict("os.environ", {}, clear=True) @patch.object(OTLPMetricExporter, "_export", return_value=Mock(ok=True)) def test_exporter_metrics_disabled_after_set_meter_provider(self, _mock_export): diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index a907a8e0c4..df7d5ee68c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -3,6 +3,7 @@ # pylint: disable=protected-access +import logging import threading import time import unittest @@ -27,6 +28,7 @@ from opentelemetry.exporter.otlp.proto.http.version import __version__ from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( ExportLogsServiceRequest, + ExportLogsServiceResponse, ) from opentelemetry.sdk._logs import ReadWriteLogRecord from opentelemetry.sdk._logs.export import LogRecordExportResult @@ -431,6 +433,43 @@ def test_2xx_status_code(self, mock_otlp_metric_exporter): LogRecordExportResult.SUCCESS, ) + @patch.object(Session, "post") + def test_partial_success_logs_warning(self, mock_post): + """A partial-success response with rejected log records logs a warning.""" + response = ExportLogsServiceResponse() + response.partial_success.rejected_log_records = 2 + response.partial_success.error_message = "some logs were dropped" + resp = Response() + resp.status_code = 200 + resp._content = response.SerializeToString() + mock_post.return_value = resp + + with self.assertLogs(level=WARNING) as warning: + self.assertEqual( + OTLPLogExporter().export(self._get_sdk_log_data()), + LogRecordExportResult.SUCCESS, + ) + self.assertIn("2 items rejected", warning.output[0]) + self.assertIn("some logs were dropped", warning.output[0]) + + @patch.object(Session, "post") + def test_full_success_logs_nothing(self, mock_post): + """A fully successful (empty partial_success) response logs nothing.""" + resp = Response() + resp.status_code = 200 + resp._content = ExportLogsServiceResponse().SerializeToString() + mock_post.return_value = resp + + logger = logging.getLogger( + "opentelemetry.exporter.otlp.proto.http._common" + ) + with patch.object(logger, "warning") as mock_warning: + self.assertEqual( + OTLPLogExporter().export(self._get_sdk_log_data()), + LogRecordExportResult.SUCCESS, + ) + mock_warning.assert_not_called() + @patch.dict("os.environ", {OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED: " true "}) @patch.object(Session, "post") def test_retry_timeout(self, mock_post): diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py index b577f2b7f4..0aea184c4a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import gzip +import logging import threading import time import unittest @@ -26,6 +27,9 @@ OTLPSpanExporter, ) from opentelemetry.exporter.otlp.proto.http.version import __version__ +from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( + ExportTraceServiceResponse, +) from opentelemetry.sdk.environment_variables import ( _OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER, OTEL_EXPORTER_OTLP_CERTIFICATE, @@ -286,6 +290,43 @@ def test_2xx_status_code(self, mock_otlp_metric_exporter): self.assertEqual(OTLPSpanExporter().export(MagicMock()), SpanExportResult.SUCCESS) + @patch.object(Session, "post") + def test_partial_success_logs_warning(self, mock_post): + """A partial-success response with rejected spans logs a warning.""" + response = ExportTraceServiceResponse() + response.partial_success.rejected_spans = 3 + response.partial_success.error_message = "some spans were dropped" + resp = Response() + resp.status_code = 200 + resp._content = response.SerializeToString() + mock_post.return_value = resp + + with self.assertLogs(level=WARNING) as warning: + self.assertEqual( + OTLPSpanExporter().export([BASIC_SPAN]), + SpanExportResult.SUCCESS, + ) + self.assertIn("3 items rejected", warning.output[0]) + self.assertIn("some spans were dropped", warning.output[0]) + + @patch.object(Session, "post") + def test_full_success_logs_nothing(self, mock_post): + """A fully successful (empty partial_success) response logs nothing.""" + resp = Response() + resp.status_code = 200 + resp._content = ExportTraceServiceResponse().SerializeToString() + mock_post.return_value = resp + + logger = logging.getLogger( + "opentelemetry.exporter.otlp.proto.http._common" + ) + with patch.object(logger, "warning") as mock_warning: + self.assertEqual( + OTLPSpanExporter().export([BASIC_SPAN]), + SpanExportResult.SUCCESS, + ) + mock_warning.assert_not_called() + @patch.dict("os.environ", {}, clear=True) @patch.object(OTLPSpanExporter, "_export", return_value=Mock(ok=True)) def test_exporter_metrics_disabled_by_default(self, _mock_export): From 93b72ac910acf404949f5620dfb776a0bb804f29 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 22 Jul 2026 08:37:30 -0500 Subject: [PATCH 2/2] Rename changelog fragment to match PR number --- .changelog/{0000.fixed => 13.fixed} | 0 .../tests/test_otlp_exporter_mixin.py | 28 +++++-------------- .../otlp/proto/http/_log_exporter/__init__.py | 4 +-- .../proto/http/metric_exporter/__init__.py | 4 +-- .../proto/http/trace_exporter/__init__.py | 4 +-- .../metrics/test_otlp_metrics_exporter.py | 4 +-- .../tests/test_proto_log_exporter.py | 4 +-- .../tests/test_proto_span_exporter.py | 4 +-- 8 files changed, 13 insertions(+), 39 deletions(-) rename .changelog/{0000.fixed => 13.fixed} (100%) diff --git a/.changelog/0000.fixed b/.changelog/13.fixed similarity index 100% rename from .changelog/0000.fixed rename to .changelog/13.fixed 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 16f5400f59..4ca8cfa1cc 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 @@ -139,13 +139,9 @@ def Export(self, request, context): response = ExportTraceServiceResponse() if self.optional_rejected_spans is not None: - response.partial_success.rejected_spans = ( - self.optional_rejected_spans - ) + response.partial_success.rejected_spans = self.optional_rejected_spans if self.optional_partial_error_message is not None: - response.partial_success.error_message = ( - self.optional_partial_error_message - ) + response.partial_success.error_message = self.optional_partial_error_message return response @@ -400,13 +396,9 @@ def test_partial_success_logs_warning(self): ), self.server, ) - exporter = OTLPSpanExporterForTesting( - insecure=True, meter_provider=self.meter_provider - ) + exporter = OTLPSpanExporterForTesting(insecure=True, meter_provider=self.meter_provider) with self.assertLogs(level=WARNING) as warning: - self.assertEqual( - exporter.export([self.span]), SpanExportResult.SUCCESS - ) + self.assertEqual(exporter.export([self.span]), SpanExportResult.SUCCESS) self.assertIn("4 items rejected", warning.output[0]) self.assertIn("some spans were dropped", warning.output[0]) @@ -416,16 +408,10 @@ def test_full_success_logs_nothing(self): TraceServiceServicerWithExportParams(StatusCode.OK), self.server, ) - exporter = OTLPSpanExporterForTesting( - insecure=True, meter_provider=self.meter_provider - ) - exporter_logger = getLogger( - "opentelemetry.exporter.otlp.proto.grpc.exporter" - ) + exporter = OTLPSpanExporterForTesting(insecure=True, meter_provider=self.meter_provider) + exporter_logger = getLogger("opentelemetry.exporter.otlp.proto.grpc.exporter") with patch.object(exporter_logger, "warning") as mock_warning: - self.assertEqual( - exporter.export([self.span]), SpanExportResult.SUCCESS - ) + self.assertEqual(exporter.export([self.span]), SpanExportResult.SUCCESS) mock_warning.assert_not_called() @unittest.skipIf( diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index 342a3d6615..75c51c7199 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -236,9 +236,7 @@ def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: - _log_partial_success( - resp.content, ExportLogsServiceResponse - ) + _log_partial_success(resp.content, ExportLogsServiceResponse) return LogRecordExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index d071e011ca..94cc8df546 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -290,9 +290,7 @@ def _export_with_retries( try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: - _log_partial_success( - resp.content, ExportMetricsServiceResponse - ) + _log_partial_success(resp.content, ExportMetricsServiceResponse) return MetricExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py index 2979a474d9..15ff1ba795 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py @@ -231,9 +231,7 @@ def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: try: resp = self._export(serialized_data, deadline_sec - time()) if resp.ok: - _log_partial_success( - resp.content, ExportTraceServiceResponse - ) + _log_partial_success(resp.content, ExportTraceServiceResponse) return SpanExportResult.SUCCESS except requests.exceptions.RequestException as error: reason = error diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py index 0843acf4f9..4b111c1aa7 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py @@ -1270,9 +1270,7 @@ def test_full_success_logs_nothing(self, mock_post): resp._content = ExportMetricsServiceResponse().SerializeToString() mock_post.return_value = resp - logger = logging.getLogger( - "opentelemetry.exporter.otlp.proto.http._common" - ) + logger = logging.getLogger("opentelemetry.exporter.otlp.proto.http._common") with patch.object(logger, "warning") as mock_warning: self.assertEqual( OTLPMetricExporter().export(self.metrics["sum_int"]), diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index df7d5ee68c..af0f456943 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -460,9 +460,7 @@ def test_full_success_logs_nothing(self, mock_post): resp._content = ExportLogsServiceResponse().SerializeToString() mock_post.return_value = resp - logger = logging.getLogger( - "opentelemetry.exporter.otlp.proto.http._common" - ) + logger = logging.getLogger("opentelemetry.exporter.otlp.proto.http._common") with patch.object(logger, "warning") as mock_warning: self.assertEqual( OTLPLogExporter().export(self._get_sdk_log_data()), diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py index 0aea184c4a..97b1758b72 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py @@ -317,9 +317,7 @@ def test_full_success_logs_nothing(self, mock_post): resp._content = ExportTraceServiceResponse().SerializeToString() mock_post.return_value = resp - logger = logging.getLogger( - "opentelemetry.exporter.otlp.proto.http._common" - ) + logger = logging.getLogger("opentelemetry.exporter.otlp.proto.http._common") with patch.object(logger, "warning") as mock_warning: self.assertEqual( OTLPSpanExporter().export([BASIC_SPAN]),