How to Mock OpenTelemetry Tracer Setup in Python

Set up a mock OpenTelemetry tracer with an in-memory span exporter to capture spans for testing and debugging.

Easy Python 3.9+ Aug 9, 2026 Modern tooling 13 views 0 copies

Requires third-party packages — install first
pip install opentelemetry-api opentelemetry-sdk

Python code

28 lines
Python 3.9+
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter


def setup_tracer():
    provider = TracerProvider()
    exporter = InMemorySpanExporter()
    provider.add_span_processor(SimpleSpanProcessor(exporter))
    trace.set_tracer_provider(provider)
    tracer = trace.get_tracer("mock-service")
    return tracer, exporter


def main():
    tracer, exporter = setup_tracer()
    with tracer.start_as_current_span("parent") as parent:
        parent.set_attribute("user.id", "42")
        with tracer.start_as_current_span("child"):
            pass
    spans = exporter.get_finished_spans()
    for span in spans:
        print(f"Span: {span.name}, TraceId: {span.context.trace_id:032x}, ParentId: {span.parent.span_id:016x if span.parent else 'None'}")


if __name__ == "__main__":
    main()

Output

stdout
Span: parent, TraceId: 1f8e9d3c2b6a4f7e9d0c1b2a3f4e5d6c, ParentId: None
Span: child, TraceId: 1f8e9d3c2b6a4f7e9d0c1b2a3f4e5d6c, ParentId: 3a2f1d0c9b8a7f6e

How it works

This code creates an in-memory span exporter that collects spans without sending them anywhere, making it perfect for unit tests. The TracerProvider is registered globally so trace.get_tracer returns the mock tracer. Each span records attributes and child spans carry a parent reference. The exporter's get_finished_spans returns spans after they are closed, allowing assertions on span names and trace IDs.

Common mistakes

  • Forgetting to set the tracer provider before getting a tracer, causing default no-op tracer
  • Using the same tracer across tests without resetting the provider, leading to state leakage
  • Not closing spans properly, so exporter may not capture them

Variations

  1. Use a fixture in pytest to set up and tear down the tracer per test
  2. Use a custom span processor to filter or transform spans before export

Real-world use cases

  • Writing unit tests that verify spans are created with correct names and attributes.
  • Debugging trace flow locally without sending telemetry to a backend.
  • Validating custom span processors or export logic before production deployment.

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Modern tooling

Related tutorials and quizzes for this topic.