Skip to content

Commit

Permalink
Recreate span on every run of a decorated function (#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-ryzhov committed Jan 4, 2021
1 parent bd8db6e commit 336af87
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- `opentelemetry-exporter-zipkin` Updated zipkin exporter status code and error tag
([#1486](https://github.com/open-telemetry/opentelemetry-python/pull/1486))
- 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
Expand Down
4 changes: 3 additions & 1 deletion opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
31 changes: 31 additions & 0 deletions opentelemetry-sdk/tests/trace/test_trace.py
Expand Up @@ -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)
Expand Down

0 comments on commit 336af87

Please sign in to comment.