This example shows a Span
used with RequestHandler
, which is used as a middleware (as in web frameworks) to manage a new Span
per operation through its before_request()
/after_response()
methods.
Implementation details:
- For
threading
, no activeSpan
is consumed as the tasks may be run concurrently on different threads, and an explicitSpanContext
has to be saved to be used as parent. - For
gevent
andasyncio
, as no automaticSpan
propagation is done, an explicitSpan
has to be saved to be used as parent (observe an instrumentation library could help to do that implicitly - we stick to the simplest case, though). - For
tornado
andcontextvars
, as parentSpan
propagates automatically (even if the tasks are called through different coroutines), we do leverage the activeSpan
.
RequestHandler implementation:
def before_request(self, request, request_context):
# If we should ignore the active Span, use any passed SpanContext
# as the parent. Else, use the active one.
if self.ignore_active_span:
# Used by threading, gevent and asyncio.
span = self.tracer.start_span('send',
child_of=self.context,
ignore_active_span=True)
else:
# Used by tornado and contextvars.
span = self.tracer.start_span('send')