# OpenTracing Shim for OpenTelemetry

The OpenTelemetry OpenTracing shim is a library which allows an easy migration from OpenTracing to OpenTelemetry.

The shim consists of a set of classes which implement the OpenTracing Python API while using OpenTelemetry constructs behind the scenes. Its purpose is to allow applications which are already instrumented using OpenTracing to start using OpenTelemetry with a minimal effort, without having to rewrite large portions of the codebase.

To use the shim, a `TracerShim` instance is created and then used as if it were an “ordinary” OpenTracing `opentracing.Tracer`, as in the following example:

    import time

    from opentelemetry import trace
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.shim.opentracing_shim import create_tracer

    # Define which OpenTelemetry Tracer provider implementation to use.
    trace.set_tracer_provider(TracerProvider())

    # Get the OpenTelemetry TracerProvider.
    tracer_provider = trace.get_tracer_provider()

    # Create an OpenTracing shim.
    shim = create_tracer(tracer_provider)

    with shim.start_active_span("ProcessHTTPRequest"):
        print("Processing HTTP request")
        # Sleeping to mock real work.
        time.sleep(0.1)
        with shim.start_active_span("GetDataFromDB"):
            print("Getting data from DB")
            # Sleeping to mock real work.
            time.sleep(0.2)

Note

While the OpenTracing Python API represents time values as the number of seconds since the epoch expressed as `float` values, the OpenTelemetry Python API represents time values as the number of nanoseconds since the epoch expressed as `int` values. This fact requires the OpenTracing shim to convert time values back and forth between the two representations, which involves floating point arithmetic.

Due to the way computers represent floating point values in hardware, representation of decimal floating point values in binary-based hardware is imprecise by definition.

The above results in slight imprecisions in time values passed to the shim via the OpenTracing API when comparing the value passed to the shim and the value stored in the OpenTelemetry `opentelemetry.trace.Span` object behind the scenes. This is not a bug in this library or in Python. Rather, this is a generic problem which stems from the fact that not every decimal floating point number can be correctly represented in binary, and therefore affects other libraries and programming languages as well. More information about this problem can be found in the Floating Point Arithmetic: Issues and Limitations section of the Python documentation.

While testing this library, the aforementioned imprecisions were observed to be of less than a microsecond.

## API

opentelemetry.shim.opentracing_shim.create_tracer(otel_tracer_provider)

  Creates a `TracerShim` object from the provided OpenTelemetry `opentelemetry.trace.TracerProvider`.

  The returned `TracerShim` is an implementation of `opentracing.Tracer` using OpenTelemetry under the hood.

  Parameters:

    otel_tracer_provider (`TracerProvider`) – A tracer from this provider will be used to perform the actual tracing when user code is instrumented using the OpenTracing API.

  Return type:

    `TracerShim`

  Returns:

    The created `TracerShim`.

class opentelemetry.shim.opentracing_shim.SpanContextShim(otel_context)

  Implements `opentracing.SpanContext` by wrapping a `opentelemetry.trace.SpanContext` object.

  Parameters:

    otel_context (`SpanContext`) – A `opentelemetry.trace.SpanContext` to be used for constructing the `SpanContextShim`.

  unwrap()

    Returns the wrapped `opentelemetry.trace.SpanContext` object.

    Return type:

      `SpanContext`

    Returns:

      The `opentelemetry.trace.SpanContext` object wrapped by this `SpanContextShim`.

  property baggage: Context

    Returns the `baggage` associated with this object

class opentelemetry.shim.opentracing_shim.SpanShim(tracer, context, span)

  Wraps a `opentelemetry.trace.Span` object.

  Parameters:

    - tracer – The `opentracing.Tracer` that created this `SpanShim`.

    - context (`SpanContextShim`) – A `SpanContextShim` which contains the context for this `SpanShim`.

    - span – A `opentelemetry.trace.Span` to wrap.

  unwrap()

    Returns the wrapped `opentelemetry.trace.Span` object.

    Returns:

      The `opentelemetry.trace.Span` object wrapped by this `SpanShim`.

  set_operation_name(operation_name)

    Updates the name of the wrapped OpenTelemetry span.

    Parameters:

      operation_name (`str`) – The new name to be used for the underlying `opentelemetry.trace.Span` object.

    Return type:

      `SpanShim`

    Returns:

      Returns this `SpanShim` instance to allow call chaining.

  finish(finish_time=None)

    Ends the OpenTelemetry span wrapped by this `SpanShim`.

    If finish_time is provided, the time value is converted to the OpenTelemetry time format (number of nanoseconds since the epoch, expressed as an integer) and passed on to the OpenTelemetry tracer when ending the OpenTelemetry span. If finish_time isn’t provided, it is up to the OpenTelemetry tracer implementation to generate a timestamp when ending the span.

    Parameters:

      finish_time (`float` | `None`) – A value that represents the finish time expressed as the number of seconds since the epoch as returned by `time.time()`.

  set_tag(key, value)

    Sets an OpenTelemetry attribute on the wrapped OpenTelemetry span.

    Parameters:

      - key (`str`) – A tag key.

      - value (`TypeVar`(`ValueT`, `int`, `float`, `bool`, `str`)) – A tag value.

    Return type:

      `SpanShim`

    Returns:

      Returns this `SpanShim` instance to allow call chaining.

  log_kv(key_values, timestamp=None)

    Logs an event for the wrapped OpenTelemetry span.

    Note

    The OpenTracing API defines the values of key_values to be of any type. However, the OpenTelemetry API requires that the values be any one of the types defined in `opentelemetry.trace.util.Attributes` therefore, only these types are supported as values.

    Parameters:

      - key_values (`Mapping`[`str`, `str` | `bool` | `int` | `float` | `Sequence`[`str`] | `Sequence`[`bool`] | `Sequence`[`int`] | `Sequence`[`float`]] | `None`) – A dictionary as specified in `opentelemetry.trace.util.Attributes`.

      - timestamp (`float` | `None`) – Timestamp of the OpenTelemetry event, will be generated automatically if omitted.

    Return type:

      `SpanShim`

    Returns:

      Returns this `SpanShim` instance to allow call chaining.

  log(**kwargs)

    DEPRECATED

  log_event(event, payload=None)

    DEPRECATED

  set_baggage_item(key, value)

    Stores a Baggage item in the span as a key/value pair.

    Parameters:

      - key (`str`) – A tag key.

      - value (`str`) – A tag value.

  get_baggage_item(key)

    Retrieves value of the baggage item with the given key.

    Parameters:

      key (`str`) – A tag key.

    Return type:

      `object` | `None`

    Returns:

      Returns this `SpanShim` instance to allow call chaining.

class opentelemetry.shim.opentracing_shim.ScopeShim(manager, span, span_cm=None)

  A `ScopeShim` wraps the OpenTelemetry functionality related to span activation/deactivation while using OpenTracing `opentracing.Scope` objects for presentation.

  Unlike other classes in this package, the `ScopeShim` class doesn’t wrap an OpenTelemetry class because OpenTelemetry doesn’t have the notion of “scope” (though it does have similar functionality).

  There are two ways to construct a `ScopeShim` object: using the default initializer and using the `from_context_manager()` class method.

  It is necessary to have both ways for constructing `ScopeShim` objects because in some cases we need to create the object from an OpenTelemetry `opentelemetry.trace.Span` context manager (as returned by `opentelemetry.trace.use_span()`), in which case our only way of retrieving a `opentelemetry.trace.Span` object is by calling the `__enter__()` method on the context manager, which makes the span active in the OpenTelemetry tracer; whereas in other cases we need to accept a `SpanShim` object and wrap it in a `ScopeShim`. The former is used mainly when the instrumentation code retrieves the currently-active span using `ScopeManagerShim.active`. The latter is mainly used when the instrumentation code activates a span using `ScopeManagerShim.activate()`.

  Parameters:

    - manager (`ScopeManagerShim`) – The `ScopeManagerShim` that created this `ScopeShim`.

    - span (`SpanShim`) – The `SpanShim` this `ScopeShim` controls.

    - span_cm – A Python context manager which yields an OpenTelemetry `opentelemetry.trace.Span` from its `__enter__()` method. Used by `from_context_manager()` to store the context manager as an attribute so that it can later be closed by calling its `__exit__()` method. Defaults to `None`.

  classmethod from_context_manager(manager, span_cm)

    Constructs a `ScopeShim` from an OpenTelemetry `opentelemetry.trace.Span` context manager.

    The method extracts a `opentelemetry.trace.Span` object from the context manager by calling the context manager’s `__enter__()` method. This causes the span to start in the OpenTelemetry tracer.

    Example usage:

        span = otel_tracer.start_span("TestSpan")
        span_cm = opentelemetry.trace.use_span(span)
        scope_shim = ScopeShim.from_context_manager(
            scope_manager_shim,
            span_cm=span_cm,
        )

    Parameters:

      - manager (`ScopeManagerShim`) – The `ScopeManagerShim` that created this `ScopeShim`.

      - span_cm – A context manager as returned by `opentelemetry.trace.use_span()`.

  close()

    Closes the `ScopeShim`. If the `ScopeShim` was created from a context manager, calling this method sets the active span in the OpenTelemetry tracer back to the span which was active before this `ScopeShim` was created. In addition, if the span represented by this `ScopeShim` was activated with the finish_on_close argument set to `True`, calling this method will end the span.

    Warning

    In the current state of the implementation it is possible to create a `ScopeShim` directly from a `SpanShim`, that is - without using `from_context_manager()`. For that reason we need to be able to end the span represented by the `ScopeShim` in this case, too. Please note that closing a `ScopeShim` created this way (for example as returned by `ScopeManagerShim.active()`) always ends the associated span, regardless of the value passed in finish_on_close when activating the span.

class opentelemetry.shim.opentracing_shim.ScopeManagerShim(tracer)

  Implements `opentracing.ScopeManager` by setting and getting the active `opentelemetry.trace.Span` in the OpenTelemetry tracer.

  This class keeps a reference to a `TracerShim` as an attribute. This reference is used to communicate with the OpenTelemetry tracer. It is necessary to have a reference to the `TracerShim` rather than the `opentelemetry.trace.Tracer` wrapped by it because when constructing a `SpanShim` we need to pass a reference to a `opentracing.Tracer`.

  Parameters:

    tracer (`TracerShim`) – A `TracerShim` to use for setting and getting active span state.

  activate(span, finish_on_close)

    Activates a `SpanShim` and returns a `ScopeShim` which represents the active span.

    Parameters:

      - span (`SpanShim`) – A `SpanShim` to be activated.

      - finish_on_close (`bool`) – Determines whether the OpenTelemetry span should be ended when the returned `ScopeShim` is closed.

    Return type:

      `ScopeShim`

    Returns:

      A `ScopeShim` representing the activated span.

  property active: ScopeShim

    Returns a `ScopeShim` object representing the currently-active span in the OpenTelemetry tracer.

    Returns:

      A `ScopeShim` representing the active span in the OpenTelemetry tracer, or `None` if no span is currently active.

    Warning

    Calling `ScopeShim.close()` on the `ScopeShim` returned by this property always ends the corresponding span, regardless of the finish_on_close value used when activating the span. This is a limitation of the current implementation of the OpenTracing shim and is likely to be handled in future versions.

  property tracer: TracerShim

    Returns the `TracerShim` reference used by this `ScopeManagerShim` for setting and getting the active span from the OpenTelemetry tracer.

    Returns:

      The `TracerShim` used for setting and getting the active span.

    Warning

    This property is not a part of the OpenTracing API. It is used internally by the current implementation of the OpenTracing shim and will likely be removed in future versions.

class opentelemetry.shim.opentracing_shim.TracerShim(tracer)

  Wraps a `opentelemetry.trace.Tracer` object.

  This wrapper class allows using an OpenTelemetry tracer as if it were an OpenTracing tracer. It exposes the same methods as an “ordinary” OpenTracing tracer, and uses OpenTelemetry transparently for performing the actual tracing.

  This class depends on the OpenTelemetry API. Therefore, any implementation of a `opentelemetry.trace.Tracer` should work with this class.

  Parameters:

    tracer (`Tracer`) – A `opentelemetry.trace.Tracer` to use for tracing. This tracer will be invoked by the shim to create actual spans.

  unwrap()

    Returns the `opentelemetry.trace.Tracer` object that is wrapped by this `TracerShim` and used for actual tracing.

    Returns:

      The `opentelemetry.trace.Tracer` used for actual tracing.

  start_active_span(operation_name, child_of=None, references=None, tags=None, start_time=None, ignore_active_span=False, finish_on_close=True)

    Starts and activates a span. In terms of functionality, this method behaves exactly like the same method on a “regular” OpenTracing tracer. See `opentracing.Tracer.start_active_span()` for more details.

    Parameters:

      - operation_name (`str`) – Name of the operation represented by the new span from the perspective of the current service.

      - child_of (`SpanShim` | `SpanContextShim` | `None`) – A `SpanShim` or `SpanContextShim` representing the parent in a “child of” reference. If specified, the references parameter must be omitted.

      - references (`list` | `None`) – A list of `opentracing.Reference` objects that identify one or more parents of type `SpanContextShim`.

      - tags (`Mapping`[`str`, `str` | `bool` | `int` | `float` | `Sequence`[`str`] | `Sequence`[`bool`] | `Sequence`[`int`] | `Sequence`[`float`]] | `None`) – A dictionary of tags.

      - start_time (`float` | `None`) – An explicit start time expressed as the number of seconds since the epoch as returned by `time.time()`.

      - ignore_active_span (`bool`) – Ignore the currently-active span in the OpenTelemetry tracer and make the created span the root span of a new trace.

      - finish_on_close (`bool`) – Determines whether the created span should end automatically when closing the returned `ScopeShim`.

    Return type:

      `ScopeShim`

    Returns:

      A `ScopeShim` that is already activated by the `ScopeManagerShim`.

  start_span(operation_name=None, child_of=None, references=None, tags=None, start_time=None, ignore_active_span=False)

    Implements the `start_span()` method from the base class.

    Starts a span. In terms of functionality, this method behaves exactly like the same method on a “regular” OpenTracing tracer. See `opentracing.Tracer.start_span()` for more details.

    Parameters:

      - operation_name (`str` | `None`) – Name of the operation represented by the new span from the perspective of the current service.

      - child_of (`SpanShim` | `SpanContextShim` | `None`) – A `SpanShim` or `SpanContextShim` representing the parent in a “child of” reference. If specified, the references parameter must be omitted.

      - references (`list` | `None`) – A list of `opentracing.Reference` objects that identify one or more parents of type `SpanContextShim`.

      - tags (`Mapping`[`str`, `str` | `bool` | `int` | `float` | `Sequence`[`str`] | `Sequence`[`bool`] | `Sequence`[`int`] | `Sequence`[`float`]] | `None`) – A dictionary of tags.

      - start_time (`float` | `None`) – An explicit start time expressed as the number of seconds since the epoch as returned by `time.time()`.

      - ignore_active_span (`bool`) – Ignore the currently-active span in the OpenTelemetry tracer and make the created span the root span of a new trace.

    Return type:

      `SpanShim`

    Returns:

      An already-started `SpanShim` instance.

  inject(span_context, format, carrier)

    Injects `span_context` into `carrier`.

    See base class for more details.

    Parameters:

      - span_context – The `opentracing.SpanContext` to inject.

      - format (`object`) – a Python object instance that represents a given carrier format. `format` may be of any type, and `format` equality is defined by Python `==` operator.

      - carrier (`object`) – the format-specific carrier object to inject into

  extract(format, carrier)

    Returns an `opentracing.SpanContext` instance extracted from a `carrier`.

    See base class for more details.

    Parameters:

      - format (`object`) – a Python object instance that represents a given carrier format. `format` may be of any type, and `format` equality is defined by python `==` operator.

      - carrier (`object`) – the format-specific carrier object to extract from

    Returns:

      An `opentracing.SpanContext` extracted from `carrier` or `None` if no such `SpanContext` could be found.