diff --git a/CHANGELOG.md b/CHANGELOG.md index fd078ca64a..54dfdc6527 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.9.1-0.28b1...HEAD) +### Fixed + +- `opentelemetry-instrumentation-logging` retrieves service name defensively. + ([#890](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/890)) + ## [1.9.1-0.28b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.9.1-0.28b1) - 2022-01-29 diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py index 4671f8707f..ae6b992dd1 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py @@ -76,20 +76,29 @@ def instrumentation_dependencies(self) -> Collection[str]: return _instruments def _instrument(self, **kwargs): - service_name = "" - provider = kwargs.get("tracer_provider", None) or get_tracer_provider() - resource = provider.resource if provider else None - if resource: - service_name = resource.attributes.get("service.name") + provider = kwargs.get("tracer_provider", None) or get_tracer_provider() old_factory = logging.getLogRecordFactory() LoggingInstrumentor._old_factory = old_factory + service_name = None + def record_factory(*args, **kwargs): record = old_factory(*args, **kwargs) record.otelSpanID = "0" record.otelTraceID = "0" + + nonlocal service_name + if service_name is None: + resource = getattr(provider, "resource", None) + if resource: + service_name = ( + resource.attributes.get("service.name") or "" + ) + else: + service_name = "" + record.otelServiceName = service_name span = get_current_span() diff --git a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py index b5ba4e4a93..45d2d82f58 100644 --- a/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py +++ b/instrumentation/opentelemetry-instrumentation-logging/tests/test_logging.py @@ -13,6 +13,7 @@ # limitations under the License. import logging +from typing import Optional from unittest import mock import pytest @@ -22,7 +23,45 @@ LoggingInstrumentor, ) from opentelemetry.test.test_base import TestBase -from opentelemetry.trace import get_tracer +from opentelemetry.trace import ProxyTracer, get_tracer + + +class FakeTracerProvider: + def get_tracer( + self, + instrumenting_module_name: str, + instrumenting_library_version: Optional[str] = None, + schema_url: Optional[str] = None, + ) -> ProxyTracer: + return ProxyTracer( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + ) + + +class TestLoggingInstrumentorProxyTracerProvider(TestBase): + @pytest.fixture(autouse=True) + def inject_fixtures(self, caplog): + self.caplog = caplog # pylint: disable=attribute-defined-outside-init + + def setUp(self): + super().setUp() + LoggingInstrumentor().instrument(tracer_provider=FakeTracerProvider()) + + def tearDown(self): + super().tearDown() + LoggingInstrumentor().uninstrument() + + def test_trace_context_injection(self): + with self.caplog.at_level(level=logging.INFO): + logger = logging.getLogger("test logger") + logger.info("hello") + self.assertEqual(len(self.caplog.records), 1) + record = self.caplog.records[0] + self.assertEqual(record.otelSpanID, "0") + self.assertEqual(record.otelTraceID, "0") + self.assertEqual(record.otelServiceName, "") class TestLoggingInstrumentor(TestBase):