From 96941a7a4b63c495e1a0bf9c7c4ef25f9c706059 Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:06:11 -0300 Subject: [PATCH 1/7] fix: capture the fully qualified type name for raised exceptions in spans --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 0110a5c0e0..5a52a38603 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -994,9 +994,11 @@ def record_exception( traceback.format_exception( type(exception), value=exception, tb=exception.__traceback__ ) - ) + ) + module = exception.__class__.__module__ if exception.__class__.__module__ != "builtins" else "" + exc_type = f"{module}.{exception.__class__.__qualname__}" if module else exception.__class__.__qualname__ _attributes: MutableMapping[str, types.AttributeValue] = { - "exception.type": exception.__class__.__name__, + "exception.type": exc_type, "exception.message": str(exception), "exception.stacktrace": stacktrace, "exception.escaped": str(escaped), From 859e0bb5d48c9c15850e0ab6f488ec5fb057ae19 Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:24:09 -0300 Subject: [PATCH 2/7] test: add test_record_exception_fqn --- .../src/opentelemetry/sdk/trace/__init__.py | 13 +++++++--- opentelemetry-sdk/tests/trace/test_trace.py | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 5a52a38603..97e44c3d02 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -994,9 +994,16 @@ def record_exception( traceback.format_exception( type(exception), value=exception, tb=exception.__traceback__ ) - ) - module = exception.__class__.__module__ if exception.__class__.__module__ != "builtins" else "" - exc_type = f"{module}.{exception.__class__.__qualname__}" if module else exception.__class__.__qualname__ + ) + module = ( + exception.__module__ + if exception.__class__.__module__ != "builtins" + else "" + ) + exc_type = ( + f"{module}.{exception.__class__.__qualname__}" + if module else exception.__class__.__qualname__ + ) _attributes: MutableMapping[str, types.AttributeValue] = { "exception.type": exc_type, "exception.message": str(exception), diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 5441bed6dd..8b7a1339f0 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -636,6 +636,10 @@ def test_events(self): self.assertEqual(span.events, tuple(events)) +class DummyError(Exception): + pass + + class TestSpan(unittest.TestCase): # pylint: disable=too-many-public-methods @@ -1144,6 +1148,28 @@ def error_status_test(context): .start_as_current_span("root") ) + def test_record_exception_fqn(self): + span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) + module_name = "dummy.module" + with mock.patch.object(DummyError, "__module__", module_name): + try: + raise DummyError("error") + except DummyError as err: + span.record_exception(err) + exception_event = span.events[0] + self.assertEqual("exception", exception_event.name) + self.assertEqual( + "error", exception_event.attributes["exception.message"] + ) + self.assertEqual( + f"{module_name}.DummyError", + exception_event.attributes["exception.type"], + ) + self.assertIn( + "DummyError: error", + exception_event.attributes["exception.stacktrace"], + ) + def test_record_exception(self): span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) try: From a06a30cdad055a9338fcab94f0d96565c7d28b0a Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Sat, 6 Apr 2024 11:10:20 -0300 Subject: [PATCH 3/7] fix: remove mock from tests and improve get qualname --- .../src/opentelemetry/sdk/trace/__init__.py | 7 ++++--- opentelemetry-sdk/tests/trace/test_trace.py | 11 ++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 97e44c3d02..7abf2f2c0e 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -997,12 +997,13 @@ def record_exception( ) module = ( exception.__module__ - if exception.__class__.__module__ != "builtins" + if type(exception).__module__ != "builtins" else "" ) + qualname = type(exception).__qualname__ exc_type = ( - f"{module}.{exception.__class__.__qualname__}" - if module else exception.__class__.__qualname__ + f"{module}.{qualname}" + if module else qualname ) _attributes: MutableMapping[str, types.AttributeValue] = { "exception.type": exc_type, diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 8b7a1339f0..0220ae726c 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -1150,19 +1150,16 @@ def error_status_test(context): def test_record_exception_fqn(self): span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) - module_name = "dummy.module" - with mock.patch.object(DummyError, "__module__", module_name): - try: - raise DummyError("error") - except DummyError as err: - span.record_exception(err) + exception = DummyError("error") + exception_type = f"{exception.__module__}.{type(exception).__qualname__}" + span.record_exception(exception) exception_event = span.events[0] self.assertEqual("exception", exception_event.name) self.assertEqual( "error", exception_event.attributes["exception.message"] ) self.assertEqual( - f"{module_name}.DummyError", + exception_type, exception_event.attributes["exception.type"], ) self.assertIn( From 884d8babbac2fe53c336834b30cf4f306e719b7a Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Mon, 8 Apr 2024 07:43:16 -0300 Subject: [PATCH 4/7] fix: improve if statements and hardcode exception_type in tests --- .../src/opentelemetry/sdk/trace/__init__.py | 13 +++---------- opentelemetry-sdk/tests/trace/test_trace.py | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 7abf2f2c0e..a82aa1c1d3 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -995,18 +995,11 @@ def record_exception( type(exception), value=exception, tb=exception.__traceback__ ) ) - module = ( - exception.__module__ - if type(exception).__module__ != "builtins" - else "" - ) + module = type(exception).__module__ qualname = type(exception).__qualname__ - exc_type = ( - f"{module}.{qualname}" - if module else qualname - ) + exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname _attributes: MutableMapping[str, types.AttributeValue] = { - "exception.type": exc_type, + "exception.type": exception_type, "exception.message": str(exception), "exception.stacktrace": stacktrace, "exception.escaped": str(escaped), diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 0220ae726c..72c7095da7 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -1151,7 +1151,7 @@ def error_status_test(context): def test_record_exception_fqn(self): span = trace._Span("name", mock.Mock(spec=trace_api.SpanContext)) exception = DummyError("error") - exception_type = f"{exception.__module__}.{type(exception).__qualname__}" + exception_type = "tests.trace.test_trace.DummyError" span.record_exception(exception) exception_event = span.events[0] self.assertEqual("exception", exception_event.name) From 5bfc127d262fe85c3361311a422d9614f3552dd4 Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Mon, 8 Apr 2024 07:45:53 -0300 Subject: [PATCH 5/7] chore: lint --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index a82aa1c1d3..033720aa33 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -997,7 +997,11 @@ def record_exception( ) module = type(exception).__module__ qualname = type(exception).__qualname__ - exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname + exception_type = ( + f"{module}.{qualname}" + if module and module != "builtins" + else qualname + ) _attributes: MutableMapping[str, types.AttributeValue] = { "exception.type": exception_type, "exception.message": str(exception), From 9976fc0c97825ca592e3f40bfe3097ab2da0e83a Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:37:12 -0300 Subject: [PATCH 6/7] chore: add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 122c50334a..6a7c8b0a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3798](https://github.com/open-telemetry/opentelemetry-python/pull/3798)) - Fix otlp exporter to export log_record.observed_timestamp ([#3785](https://github.com/open-telemetry/opentelemetry-python/pull/3785)) +- Add capture the fully qualified type name for raised exceptions in spans + ([#3837](https://github.com/open-telemetry/opentelemetry-python/pull/3837)) ## Version 1.24.0/0.45b0 (2024-03-28) From 18b28eacea156bd2c39197e3d3a9004dee27d86e Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:57:52 -0300 Subject: [PATCH 7/7] chore: lint --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 033720aa33..c07f4f42c4 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -998,8 +998,8 @@ def record_exception( module = type(exception).__module__ qualname = type(exception).__qualname__ exception_type = ( - f"{module}.{qualname}" - if module and module != "builtins" + f"{module}.{qualname}" + if module and module != "builtins" else qualname ) _attributes: MutableMapping[str, types.AttributeValue] = {