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.
pip install opentelemetry-api opentelemetry-sdk
Python code
28 linesfrom 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
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
- Use a fixture in pytest to set up and tear down the tracer per test
- 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
More from Modern tooling
- Build a Recipe Runner Mock in Python easy
- Build a Textual TUI App Skeleton in Python easy
- Configure ruff linter rules in pyproject.toml with Python easy
- Data Conversion Helper Functions in Python easy
- How to Bind and Mock structlog Context in Python medium
- How to Build a Chainable Filter Helper in Python easy
Keep learning
Related tutorials and quizzes for this topic.