BasicTracer Python
basictracer is a Python implementation of the OpenTracing API, providing a simple, in-memory tracer suitable for development and testing. It allows applications to instrument code with spans, logs, and baggage, adhering to the OpenTracing specification. The current version is 3.2.0, and its release cadence is infrequent, with the last major update in 2021.
Common errors
-
basictracer.propagator.SpanContextCorruptedException: Could not extract `traceid` from carrier.
cause This error occurs when `TextPropagator.extract` (used internally by the tracer for header propagation) fails to parse expected tracing headers (e.g., `x-b3-traceid`) from the provided carrier due to malformation or absence.fixVerify that the incoming HTTP headers or other carrier data contain valid OpenTracing-compatible tracing information. If malformed headers are possible, wrap the extraction call in a `try...except SpanContextCorruptedException` block. -
TypeError: 'Span' object is not iterable
cause You are likely passing an `opentracing.Span` object directly to the `references` argument of `tracer.start_span()`. This argument expects an iterable of `opentracing.Reference` objects, not a raw Span.fixCorrectly use `opentracing.ChildOf(parent_span)` or `opentracing.FollowsFrom(span_context)` to create `Reference` objects, and pass them within a list or tuple to the `references` argument, e.g., `tracer.start_span('child', references=[opentracing.ChildOf(parent_span)])`. -
SyntaxError: invalid syntax (on lines related to type hints or f-strings)
cause You are attempting to run `basictracer` version 3.1.0 or newer on a Python environment older than 3.5. These versions leverage newer Python features.fixUpgrade your Python environment to version 3.5 or higher. Alternatively, if you are stuck on an older Python version, install an older `basictracer` release (e.g., `pip install 'basictracer<3.1.0'`).
Warnings
- breaking In version 3.2.0, `TextPropagator.extract` now explicitly raises `SpanContextCorruptedException` when encountering malformed or unextractable tracing headers. Previously, it might have silently failed or returned a default context.
- breaking As of version 3.2.0, `Tracer.start_span` performs stricter type validation for the `references` argument. Passing an incorrect type (e.g., a `Span` object directly instead of an `opentracing.Reference`) will now raise a `TypeError`.
- gotcha `basictracer` is an in-memory tracer, primarily designed for development, testing, and understanding OpenTracing concepts. It does not persist or export trace data to external systems.
- gotcha Versions of `basictracer` prior to 3.1.0 do not support Python 3.5+ due to older `opentracing` dependency constraints and other factors.
Install
-
pip install basictracer
Imports
- BasicTracer
from basictracer import BasicTracer
- InMemoryRecorder
from basictracer.recorder import InMemoryRecorder
- SpanContextCorruptedException
from basictracer import SpanContextCorruptedException
from basictracer.propagator import SpanContextCorruptedException
Quickstart
import opentracing
from basictracer import BasicTracer
from basictracer.recorder import InMemoryRecorder
# Initialize an in-memory recorder to store spans
recorder = InMemoryRecorder()
# Create a BasicTracer instance
tracer = BasicTracer(recorder=recorder)
# It's common practice to set the global tracer
opentracing.set_global_tracer(tracer)
# Start a new span using the global tracer
with opentracing.start_active_span('my_operation') as scope:
span = scope.span
span.log_kv({'event': 'start_work', 'stage': 1})
# Simulate some work
result = "some data"
span.log_kv({'event': 'finish_work', 'result_len': len(result)})
# Retrieve recorded spans
print(f"Recorded {len(recorder.spans)} span(s).")
for s in recorder.spans:
print(f" Operation: {s.operation_name}, Duration: {s.duration}ns")
print(f" Logs: {s.logs}")
# Example of Child-Of span
with opentracing.start_active_span('parent_span') as parent_scope:
with opentracing.start_active_span('child_span', child_of=parent_scope.span):
pass # Child-Of span created
print(f"Total recorded spans after second block: {len(recorder.spans)}")