From c855c14bc6bc05e70f8c8960861a82dafaed5888 Mon Sep 17 00:00:00 2001 From: Anton Ryzhov Date: Mon, 7 Dec 2020 10:34:47 +0100 Subject: [PATCH] Recreate span on every run of a decorated function --- CHANGELOG.md | 3 ++ .../src/opentelemetry/sdk/trace/__init__.py | 4 ++- opentelemetry-sdk/tests/trace/test_trace.py | 31 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d0b55121b..ba5ee2754bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1285](https://github.com/open-telemetry/opentelemetry-python/pull/1285)) - Added `__repr__` for `DefaultSpan`, added `trace_flags` to `__repr__` of `SpanContext` ([#1485](https://github.com/open-telemetry/opentelemetry-python/pull/1485)]) +### Changed +- Recreate span on every run of a `start_as_current_span`-decorated function + ([#1451](https://github.com/open-telemetry/opentelemetry-python/pull/1451)) ## [0.16b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.16b1) - 2020-11-26 ### Added diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index cd087a7314e..c8dec7bc62e 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -742,6 +742,7 @@ def __init__( self.ids_generator = ids_generator self.instrumentation_info = instrumentation_info + @contextmanager def start_as_current_span( self, name: str, @@ -763,7 +764,8 @@ def start_as_current_span( record_exception=record_exception, set_status_on_exception=set_status_on_exception, ) - return self.use_span(span, end_on_exit=True) + with self.use_span(span, end_on_exit=True) as span_context: + yield span_context def start_span( # pylint: disable=too-many-locals self, diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 6879b6390d3..bfefdfcb42a 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -414,6 +414,37 @@ def test_start_as_current_span_explicit(self): self.assertIs(trace_api.get_current_span(), root) self.assertIsNotNone(child.end_time) + def test_start_as_current_span_decorator(self): + tracer = new_tracer() + + self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN) + + @tracer.start_as_current_span("root") + def func(): + root = trace_api.get_current_span() + + with tracer.start_as_current_span("child") as child: + self.assertIs(trace_api.get_current_span(), child) + self.assertIs(child.parent, root.get_span_context()) + + # After exiting the child's scope the parent should become the + # current span again. + self.assertIs(trace_api.get_current_span(), root) + self.assertIsNotNone(child.end_time) + + return root + + root1 = func() + + self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN) + self.assertIsNotNone(root1.end_time) + + # Second call must create a new span + root2 = func() + self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN) + self.assertIsNotNone(root2.end_time) + self.assertIsNot(root1, root2) + def test_explicit_span_resource(self): resource = resources.Resource.create({}) tracer_provider = trace.TracerProvider(resource=resource)