From fc94cd4168c6b9fb27ad3a72cbf12505fdf4f661 Mon Sep 17 00:00:00 2001 From: Owais Lone Date: Fri, 25 Sep 2020 06:49:33 +0530 Subject: [PATCH] Record exception on context manager exit This updates the tracer context manager to automatically record exceptions as events on exit if an exception was raised within the context manager's context. --- .../src/opentelemetry/sdk/trace/__init__.py | 1 + opentelemetry-sdk/tests/trace/test_trace.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 13819ed35b0..b6af5f5391c 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -796,6 +796,7 @@ def use_span( context_api.detach(token) except Exception as error: # pylint: disable=broad-except + span.record_exception(error) if ( isinstance(span, Span) and span.status is None diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index fdf85ef19b5..92b2cd6d946 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -799,6 +799,24 @@ def test_record_exception(self): exception_event.attributes["exception.stacktrace"], ) + def test_record_exception_context_manager(self): + try: + with self.tracer.start_as_current_span("span") as span: + raise RuntimeError("example error") + except RuntimeError: + pass + finally: + self.assertEqual(len(span.events), 1) + event = span.events[0] + self.assertEqual("exception", event.name) + self.assertEqual("RuntimeError", event.attributes["exception.type"]) + self.assertEqual("example error", event.attributes["exception.message"]) + + stacktrace = '''in test_record_exception_context_manager + raise RuntimeError("example error") +RuntimeError: example error''' + self.assertIn(stacktrace, event.attributes["exception.stacktrace"]) + def span_event_start_fmt(span_processor_name, span_name): return span_processor_name + ":" + span_name + ":start"