Skip to content

Commit d40ab67

Browse files
committed
Fixes partial success logging to apply at only 'verbose' and 'debug' levels to avoid changing default behaviors. Apply test and formatting fixes.
1 parent e008658 commit d40ab67

File tree

6 files changed

+43
-42
lines changed

6 files changed

+43
-42
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
1313
## Unreleased
1414

15-
- OTLP exporters now log partial success responses when `OTEL_LOG_LEVEL` is set to `info`, `debug`, or `verbose`.
15+
- OTLP exporters now log partial success responses at `debug` level when `OTEL_LOG_LEVEL` is set to `debug` or `verbose`.
1616
([#4805](https://github.com/open-telemetry/opentelemetry-python/pull/4805))
1717
- docs: Added sqlcommenter example
1818
([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734))

exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14-
from os import environ
1514
import sys
15+
from os import environ
1616
from typing import Dict, Literal, Optional, Sequence, Tuple, Union
1717
from typing import Sequence as TypingSequence
1818

@@ -113,7 +113,7 @@ def _translate_data(
113113
def _log_partial_success(self, partial_success):
114114
# Override that skips the "logging" module due to the possibility
115115
# of circular logic (logging -> OTLP logs export).
116-
sys.stderr.write(f"Partial success:\n{partial_success}\n")
116+
sys.stderr.write(f"Partial success:\n{partial_success}\n")
117117

118118
def export( # type: ignore [reportIncompatibleMethodOverride]
119119
self,

exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
OTEL_EXPORTER_OTLP_HEADERS,
9494
OTEL_EXPORTER_OTLP_INSECURE,
9595
OTEL_EXPORTER_OTLP_TIMEOUT,
96-
OTEL_LOG_LEVEL
96+
OTEL_LOG_LEVEL,
9797
)
9898
from opentelemetry.sdk.metrics.export import MetricExportResult, MetricsData
9999
from opentelemetry.sdk.resources import Resource as SDKResource
@@ -260,7 +260,7 @@ def _get_credentials(
260260

261261
def _should_log_partial_responses():
262262
otel_log_level = environ.get(OTEL_LOG_LEVEL, "info").lower()
263-
return otel_log_level in ["verbose", "debug", "info"]
263+
return otel_log_level in ["verbose", "debug"]
264264

265265

266266
# pylint: disable=no-member
@@ -299,7 +299,9 @@ def __init__(
299299
self._endpoint = endpoint or environ.get(
300300
OTEL_EXPORTER_OTLP_ENDPOINT, "http://localhost:4317"
301301
)
302-
self._partial_response_logging_enabled = _should_log_partial_responses()
302+
self._partial_response_logging_enabled = (
303+
_should_log_partial_responses()
304+
)
303305

304306
parsed_url = urlparse(self._endpoint)
305307

@@ -382,10 +384,12 @@ def _translate_data(
382384
pass
383385

384386
def _log_partial_success(self, partial_success):
385-
logger.info(f"Partial success:\n{partial_success}")
387+
logger.debug("Partial success:\n%s", partial_success)
386388

387389
def _process_response(self, response):
388-
if self._partial_response_logging_enabled and response.HasField("partial_success"):
390+
if self._partial_response_logging_enabled and response.HasField(
391+
"partial_success"
392+
):
389393
self._log_partial_success(response.partial_success)
390394

391395
def _export(

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414

1515
# pylint: disable=too-many-lines
1616

17-
from io import StringIO
18-
import sys
1917
import time
18+
from io import StringIO
2019
from os.path import dirname
2120
from unittest import TestCase
2221
from unittest.mock import Mock, patch
@@ -321,26 +320,26 @@ def export_log_and_deserialize(self, log_data):
321320
)
322321
return log_records
323322

324-
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "info"})
323+
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "debug"})
325324
@patch("sys.stderr", new_callable=StringIO)
326325
def test_partial_success_recorded_directly_to_stderr(self, mock_stderr):
327326
# pylint: disable=protected-access
328327
exporter = OTLPLogExporter()
329328
exporter._client = Mock()
330-
exporter._client.Export.return_value = (
331-
ExportLogsServiceResponse(
332-
partial_success=ExportLogsPartialSuccess(
333-
rejected_log_records=1,
334-
error_message="Log record dropped",
335-
)
329+
exporter._client.Export.return_value = ExportLogsServiceResponse(
330+
partial_success=ExportLogsPartialSuccess(
331+
rejected_log_records=1,
332+
error_message="Log record dropped",
336333
)
337334
)
338335

339336
exporter.export([self.log_data_1])
340337

341338
self.assertIn("Partial success:\n", mock_stderr.getvalue())
342339
self.assertIn("rejected_log_records: 1\n", mock_stderr.getvalue())
343-
self.assertIn('error_message: "Log record dropped"\n', mock_stderr.getvalue())
340+
self.assertIn(
341+
'error_message: "Log record dropped"\n', mock_stderr.getvalue()
342+
)
344343

345344
def test_exported_log_without_trace_id(self):
346345
log_records = self.export_log_and_deserialize(self.log_data_4)

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,9 @@ def test_permanent_failure(self):
538538
)
539539

540540
@patch.dict("os.environ", {}, clear=True)
541-
@patch("logging.Logger.info")
541+
@patch("logging.Logger.debug")
542542
def test_does_not_record_partial_success_if_log_level_unset(
543-
self, mock_logger_info
543+
self, mock_logger_debug
544544
):
545545
exporter = OTLPSpanExporterForTesting(insecure=True)
546546
# pylint: disable=protected-access
@@ -552,12 +552,12 @@ def test_does_not_record_partial_success_if_log_level_unset(
552552
)
553553
)
554554
exporter.export([self.span])
555-
mock_logger_info.assert_not_called()
555+
mock_logger_debug.assert_not_called()
556556

557557
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "off"})
558-
@patch("logging.Logger.info")
558+
@patch("logging.Logger.debug")
559559
def test_does_not_record_partial_success_if_log_level_off(
560-
self, mock_logger_info
560+
self, mock_logger_debug
561561
):
562562
exporter = OTLPSpanExporterForTesting(insecure=True)
563563
# pylint: disable=protected-access
@@ -569,12 +569,12 @@ def test_does_not_record_partial_success_if_log_level_off(
569569
)
570570
)
571571
exporter.export([self.span])
572-
mock_logger_info.assert_not_called()
572+
mock_logger_debug.assert_not_called()
573573

574574
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "error"})
575-
@patch("logging.Logger.info")
575+
@patch("logging.Logger.debug")
576576
def test_does_not_record_partial_success_if_log_level_error(
577-
self, mock_logger_info
577+
self, mock_logger_debug
578578
):
579579
exporter = OTLPSpanExporterForTesting(insecure=True)
580580
# pylint: disable=protected-access
@@ -586,12 +586,12 @@ def test_does_not_record_partial_success_if_log_level_error(
586586
)
587587
)
588588
exporter.export([self.span])
589-
mock_logger_info.assert_not_called()
589+
mock_logger_debug.assert_not_called()
590590

591591
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "verbose"})
592-
@patch("logging.Logger.info")
592+
@patch("logging.Logger.debug")
593593
def test_records_partial_success_if_log_level_verbose(
594-
self, mock_logger_info
594+
self, mock_logger_debug
595595
):
596596
exporter = OTLPSpanExporterForTesting(insecure=True)
597597
# pylint: disable=protected-access
@@ -604,14 +604,14 @@ def test_records_partial_success_if_log_level_verbose(
604604
partial_success=partial_success
605605
)
606606
exporter.export([self.span])
607-
mock_logger_info.assert_called_once_with(
608-
f"Partial success:\n{partial_success}"
607+
mock_logger_debug.assert_called_once_with(
608+
"Partial success:\n%s", partial_success
609609
)
610610

611611
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "debug"})
612-
@patch("logging.Logger.info")
612+
@patch("logging.Logger.debug")
613613
def test_records_partial_success_if_log_level_debug(
614-
self, mock_logger_info
614+
self, mock_logger_debug
615615
):
616616
exporter = OTLPSpanExporterForTesting(insecure=True)
617617
# pylint: disable=protected-access
@@ -624,14 +624,14 @@ def test_records_partial_success_if_log_level_debug(
624624
partial_success=partial_success
625625
)
626626
exporter.export([self.span])
627-
mock_logger_info.assert_called_once_with(
628-
f"Partial success:\n{partial_success}"
627+
mock_logger_debug.assert_called_once_with(
628+
"Partial success:\n%s", partial_success
629629
)
630630

631631
@patch.dict("os.environ", {OTEL_LOG_LEVEL: "info"})
632-
@patch("logging.Logger.info")
633-
def test_records_partial_success_if_log_level_info(
634-
self, mock_logger_info
632+
@patch("logging.Logger.debug")
633+
def test_does_not_record_partial_success_if_log_level_info(
634+
self, mock_logger_debug
635635
):
636636
exporter = OTLPSpanExporterForTesting(insecure=True)
637637
# pylint: disable=protected-access
@@ -644,6 +644,4 @@ def test_records_partial_success_if_log_level_info(
644644
partial_success=partial_success
645645
)
646646
exporter.export([self.span])
647-
mock_logger_info.assert_called_once_with(
648-
f"Partial success:\n{partial_success}"
649-
)
647+
mock_logger_debug.assert_not_called()

opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
.. envvar:: OTEL_LOG_LEVEL
5252
5353
The :envvar:`OTEL_LOG_LEVEL` environment variable sets the log level used by the SDK logger.
54-
OTLP exporters will log partial success responses when this is set to `info`, `debug`, or `verbose`.
54+
OTLP exporters will log partial success responses when this is set to `debug` or `verbose`.
5555
Default: "info"
5656
"""
5757

0 commit comments

Comments
 (0)