diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b8cfb03986..4f1cd0c79dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Fix error when no LoggerProvider configured for LoggingHandler + ([#3423](https://github.com/open-telemetry/opentelemetry-python/pull/3423)) + ## Version 1.20.0/0.41b0 (2023-09-04) - Modify Prometheus exporter to translate non-monotonic Sums into Gauges ([#3306](https://github.com/open-telemetry/opentelemetry-python/pull/3306)) - ## Version 1.19.0/0.40b0 (2023-07-13) - Drop `setuptools` runtime requirement. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py index eb5f50e9e0f..d3db94d624f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py @@ -27,6 +27,7 @@ from opentelemetry._logs import LoggerProvider as APILoggerProvider from opentelemetry._logs import LogRecord as APILogRecord from opentelemetry._logs import ( + NoOpLogger, SeverityNumber, get_logger, get_logger_provider, @@ -532,11 +533,12 @@ def _translate(self, record: logging.LogRecord) -> LogRecord: def emit(self, record: logging.LogRecord) -> None: """ - Emit a record. + Emit a record. Skip emitting if logger is NoOp. The record is translated to OTel format, and then sent across the pipeline. """ - self._logger.emit(self._translate(record)) + if not isinstance(self._logger, NoOpLogger): + self._logger.emit(self._translate(record)) def flush(self) -> None: """ diff --git a/opentelemetry-sdk/tests/logs/test_handler.py b/opentelemetry-sdk/tests/logs/test_handler.py index bb4fc3a8291..e126cac1720 100644 --- a/opentelemetry-sdk/tests/logs/test_handler.py +++ b/opentelemetry-sdk/tests/logs/test_handler.py @@ -15,7 +15,7 @@ import unittest from unittest.mock import Mock -from opentelemetry._logs import SeverityNumber +from opentelemetry._logs import NoOpLoggerProvider, SeverityNumber from opentelemetry._logs import get_logger as APIGetLogger from opentelemetry.attributes import BoundedAttributes from opentelemetry.sdk import trace @@ -64,6 +64,21 @@ def test_handler_custom_log_level(self): logger.critical("No Time For Caution") self.assertEqual(emitter_mock.emit.call_count, 2) + # pylint: disable=protected-access + def test_log_record_emit_noop(self): + noop_logger_provder = NoOpLoggerProvider() + logger_mock = APIGetLogger( + __name__, logger_provider=noop_logger_provder + ) + logger = logging.getLogger(__name__) + handler_mock = Mock(spec=LoggingHandler) + handler_mock._logger = logger_mock + handler_mock.level = logging.WARNING + logger.addHandler(handler_mock) + with self.assertLogs(level=logging.WARNING): + logger.warning("Warning message") + handler_mock._translate.assert_not_called() + def test_log_record_no_span_context(self): emitter_provider_mock = Mock(spec=LoggerProvider) emitter_mock = APIGetLogger(