diff --git a/CHANGELOG.md b/CHANGELOG.md index b383bf0f84..ba26b90d07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#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)) +- Add `code.lineno`, `code.function` and `code.filepath` to all logs + ([#3645](https://github.com/open-telemetry/opentelemetry-python/pull/3645)) ## Version 1.22.0/0.43b0 (2023-12-15) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py index cfa4d6cfa9..cbfde8d6eb 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py @@ -455,6 +455,12 @@ def _get_attributes(record: logging.LogRecord) -> Attributes: attributes = { k: v for k, v in vars(record).items() if k not in _RESERVED_ATTRS } + + # Add standard code attributes for logs. + attributes[SpanAttributes.CODE_FILEPATH] = record.pathname + attributes[SpanAttributes.CODE_FUNCTION] = record.funcName + attributes[SpanAttributes.CODE_LINENO] = record.lineno + if record.exc_info: exc_type = "" message = "" diff --git a/opentelemetry-sdk/tests/logs/test_handler.py b/opentelemetry-sdk/tests/logs/test_handler.py index e126cac172..712e5be04b 100644 --- a/opentelemetry-sdk/tests/logs/test_handler.py +++ b/opentelemetry-sdk/tests/logs/test_handler.py @@ -112,7 +112,20 @@ def test_log_record_user_attributes(self): log_record = args[0] self.assertIsNotNone(log_record) - self.assertEqual(log_record.attributes, {"http.status_code": 200}) + self.assertEqual(len(log_record.attributes), 4) + self.assertEqual(log_record.attributes["http.status_code"], 200) + self.assertTrue( + log_record.attributes[SpanAttributes.CODE_FILEPATH].endswith( + "test_handler.py" + ) + ) + self.assertEqual( + log_record.attributes[SpanAttributes.CODE_FUNCTION], + "test_log_record_user_attributes", + ) + # The line of the log statement is not a constant (changing tests may change that), + # so only check that the attribute is present. + self.assertTrue(SpanAttributes.CODE_LINENO in log_record.attributes) self.assertTrue(isinstance(log_record.attributes, BoundedAttributes)) def test_log_record_exception(self):