OpenTracing-Python 2.0.0 Released

Carlos Alberto Cortez
OpenTracing
Published in
2 min readJul 10, 2018

The 2.0.0 release of OpenTracing Python is now available.

The Scopes approach for context propagation has been adopted from Java 0.31, providing a default ScopeManager implementation for threading, as well as implementations for the asynchronous frameworks Tornado, gevent and asyncio.

ScopeManager and Scopes

Rather than manually pass spans down the call stack, tracers now retain a reference to the current active span. Every Tracer now contains a ScopeManager, which assigns a Span to each execution context (for example: a thread, a coroutine or a greenlet) via a Scope. At any moment, Tracer.active_span can be used to retrieve the Span contained in the current Scope.

The most common case is to create a new Scope and Span for the current context by using Tracer.start_active_span():

By default, new Span will use the current active Span as its parent. In the example above, child will automatically inherit from parent (this can be overridden to have an explicit parent, or none). Once the new Scope is closed, the parent scope will once again become active.

ScopeManager implementations do not automatically move Spans between threads, coroutines or greenlets (although framework instrumentation libraries may do this for you). If a transaction moves from one execution context to another, the Span tracking the work must also be passed to the new context, and activated in a new Scope.

Here’s an example of manually passing a Span between threads using a ThreadPoolExecutor:

For asynchronous frameworks, finishing Spans doesn’t need to happen in child coroutines if yielding/awaiting over them. Here an example of manually passing a Span between greenlets using gevent:

At this time, we recommend Tracer implementers start porting to the new API, while instrumentation maintainers begin preparing a 2.0.0 version of their library on a branch tagged with ot_v2.0.0 .

Changes from v1.3.0

  • Scope and ScopeManager added to the API.
  • A Scope represents an execution context. Each Scope contains a Span, and is deactivated when Scope.close() is called.
  • ScopeManager.activate(span) associates a Span with the current context, returning a new Scope.
  • ScopeManager.active() returns the currently active Scope, or else None.
  • Tracer.start_active_span() creates a new Span and automatically activates it.
  • Tracer.start_span() and Tracer.start_active_span() will automatically use the current active Span as a parent, unless the programmer passes a specified parent context or sets ignore_active_span=True. *Note*: This is a breaking change for Tracer.start_span().
  • A set of basic ScopeManager implementations for threading, Tornado, gevent and asyncio under the opentracing.scope_managers submodule.
  • MockTracer added to make it easy to test the semantics of OpenTracing instrumentation.

Changes from BasicTracer v2.2.0

  • Updated the API to use ScopeManager, using ThreadLocalScopeManager from the core API as the default value.

OpenTracing Specification and ongoing RFC.

The current API is part of an ongoing effort to include ScopeManager and Scope notion into the actual OpenTracing Specification: https://github.com/opentracing/specification/blob/master/rfc/scope_manager.md

Feel free to provide feedback on https://github.com/opentracing/specification and referencing this specific RFC document.

PyPi Packages

https://pypi.python.org/pypi/opentracing/2.0.0

https://pypi.python.org/pypi/basictracer/3.0.0

Thanks to everyone who contributed code, testing, and feedback into this release, including palazzem, yurishkuro, Kyle-Verhoog, pglombardo and many others! 🎉🎉🎉

--

--