From c4d17e9f14f3cafb6757b96eefabdc7ed4891306 Mon Sep 17 00:00:00 2001 From: gshiva Date: Thu, 25 Jan 2024 16:27:50 -0800 Subject: [PATCH] Handle HTTP 2XX responses as successful in OTLP exporters (#3623) * Handle HTTP 2XX responses as successful in OTLP exporters * Add test cases for 2XX HTTP responses * Add CHANGELOG entry * Fix lint --- CHANGELOG.md | 5 ++++- .../otlp/proto/http/_log_exporter/__init__.py | 2 +- .../otlp/proto/http/metric_exporter/__init__.py | 2 +- .../otlp/proto/http/trace_exporter/__init__.py | 2 +- .../tests/metrics/test_otlp_metrics_exporter.py | 13 ++++++++++++- .../tests/test_proto_log_exporter.py | 13 ++++++++++++- .../tests/test_proto_span_exporter.py | 13 ++++++++++++- 7 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b46a17246ad..6dd0ee3b7de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Handle HTTP 2XX responses as successful in OTLP exporters + ([#3623](https://github.com/open-telemetry/opentelemetry-python/pull/3623)) - Improve Resource Detector timeout messaging ([#3645](https://github.com/open-telemetry/opentelemetry-python/pull/3645)) ## Version 1.22.0/0.43b0 (2023-12-15) -- Prometheus exporter sanitize info metric ([#3572](https://github.com/open-telemetry/opentelemetry-python/pull/3572)) +- Prometheus exporter sanitize info metric + ([#3572](https://github.com/open-telemetry/opentelemetry-python/pull/3572)) - Remove Jaeger exporters ([#3554](https://github.com/open-telemetry/opentelemetry-python/pull/3554)) - Log stacktrace on `UNKNOWN` status OTLP export error 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 caacdbdfcab..4703b102863 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 @@ -146,7 +146,7 @@ def export(self, batch: Sequence[LogData]) -> LogExportResult: resp = self._export(serialized_data) # pylint: disable=no-else-return - if resp.status_code in (200, 202): + if resp.ok: return LogExportResult.SUCCESS elif self._retryable(resp): _logger.warning( 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 ed878dabe87..becdab257fe 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 @@ -178,7 +178,7 @@ def export( resp = self._export(serialized_data.SerializeToString()) # pylint: disable=no-else-return - if resp.status_code in (200, 202): + if resp.ok: return MetricExportResult.SUCCESS elif self._retryable(resp): _logger.warning( 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 2ab7e97e026..d98a1b84a75 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 @@ -144,7 +144,7 @@ def export(self, spans) -> SpanExportResult: resp = self._export(serialized_data) # pylint: disable=no-else-return - if resp.status_code in (200, 202): + if resp.ok: return SpanExportResult.SUCCESS elif self._retryable(resp): _logger.warning( 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 d9011322b92..c06b5db3c22 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 @@ -15,7 +15,7 @@ from logging import WARNING from os import environ from unittest import TestCase -from unittest.mock import patch +from unittest.mock import MagicMock, Mock, patch from requests import Session from requests.models import Response @@ -476,3 +476,14 @@ def test_exponential_explicit_bucket_histogram(self): OTLPMetricExporter()._preferred_aggregation[Histogram], ExplicitBucketHistogramAggregation, ) + + @patch.object(OTLPMetricExporter, "_export", return_value=Mock(ok=True)) + def test_2xx_status_code(self, mock_otlp_metric_exporter): + """ + Test that any HTTP 2XX code returns a successful result + """ + + self.assertEqual( + OTLPMetricExporter().export(MagicMock()), + MetricExportResult.SUCCESS, + ) 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 5300ce85dee..e601e5d00cb 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 @@ -16,7 +16,7 @@ import unittest from typing import List -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock, Mock, patch import requests import responses @@ -34,6 +34,7 @@ from opentelemetry.exporter.otlp.proto.http.version import __version__ from opentelemetry.sdk._logs import LogData from opentelemetry.sdk._logs import LogRecord as SDKLogRecord +from opentelemetry.sdk._logs.export import LogExportResult from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_COMPRESSION, @@ -262,3 +263,13 @@ def _get_sdk_log_data() -> List[LogData]: ) return [log1, log2, log3, log4] + + @patch.object(OTLPLogExporter, "_export", return_value=Mock(ok=True)) + def test_2xx_status_code(self, mock_otlp_metric_exporter): + """ + Test that any HTTP 2XX code returns a successful result + """ + + self.assertEqual( + OTLPLogExporter().export(MagicMock()), LogExportResult.SUCCESS + ) 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 9a1d1604a25..eb5b375e40d 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 @@ -14,7 +14,7 @@ import unittest from collections import OrderedDict -from unittest.mock import Mock, patch +from unittest.mock import MagicMock, Mock, patch import requests import responses @@ -42,6 +42,7 @@ OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, ) from opentelemetry.sdk.trace import _Span +from opentelemetry.sdk.trace.export import SpanExportResult OS_ENV_ENDPOINT = "os.env.base" OS_ENV_CERTIFICATE = "os/env/base.crt" @@ -239,3 +240,13 @@ def generate_delays(*args, **kwargs): exporter.export([span]) mock_sleep.assert_called_once_with(1) + + @patch.object(OTLPSpanExporter, "_export", return_value=Mock(ok=True)) + def test_2xx_status_code(self, mock_otlp_metric_exporter): + """ + Test that any HTTP 2XX code returns a successful result + """ + + self.assertEqual( + OTLPSpanExporter().export(MagicMock()), SpanExportResult.SUCCESS + )