Skip to main content
In this lesson we’ll instrument a small Python application using OpenTelemetry tracing. The demo app is intentionally tiny so tracing concepts are clear — the same ideas apply to other languages (JavaScript, Java, C#, etc.). By the end you’ll have a working example that prints spans locally and a clear path to send telemetry to a backend. What you’ll learn
  • How to add OpenTelemetry packages to a Python project
  • How to configure a TracerProvider and ConsoleSpanExporter
  • How to create spans that represent operations and nested child operations
  • Where to go next to export traces to a backend (OTLP, Jaeger, Zipkin)
Prerequisites
  • Python 3.7+
  • pip
Demo application (simple payment flow)
This tiny application represents a dummy payment service:
  • process_payment() starts the flow.
  • validate_card() simulates credit-card validation.
  • charge_bank() simulates charging the user’s bank.
We will instrument these functions so running the program generates trace spans for each step. Installing OpenTelemetry packages Install the core API and SDK packages:
Example of packages installed (condensed):
OpenTelemetry is split into API and SDK: the API provides the interfaces you call from application code, while the SDK provides concrete implementations (exporters, processors, and providers) that produce and export telemetry.
Configuring tracing in Python Below is a small helper that configures a tracer provider, a span processor, and a ConsoleSpanExporter. The ConsoleSpanExporter prints spans to stdout — this is useful for local development and debugging.
Instrumenting the application to generate spans Use the tracer returned by configure_tracer() to create spans. The recommended pattern is to use the context manager start_as_current_span so spans are properly nested and automatically ended. Complete instrumented example:
Running the instrumented application
Because we used ConsoleSpanExporter, you will also see formatted span output printed to the console. A simplified example of what ConsoleSpanExporter might print (exact formatting may vary by OpenTelemetry version):
Exporters and next steps When you move beyond local testing, replace ConsoleSpanExporter with an exporter for your backend. Common choices:
ExporterUse caseDocs
OTLPSend traces to the OpenTelemetry Collector or supported backendshttps://opentelemetry.io/docs/instrumentation/python/exporters/otlp/
JaegerSend traces directly to a Jaeger backendhttps://www.jaegertracing.io/
ZipkinSend traces directly to Zipkinhttps://zipkin.io/
You can also configure the OpenTelemetry Collector to receive OTLP and forward traces to many backends. See the OpenTelemetry Collector docs for pipeline examples. Best practices and considerations
  • Add meaningful span names, attributes, and events to capture the context that helps debugging (e.g., masked card identifier, user id, HTTP status).
  • Use automatic instrumentation libraries for frameworks and popular libraries when available; complement them with manual spans for business logic.
  • Keep spans short-lived and focused on logical units of work.
  • Avoid logging sensitive data to spans or attributes. Use masking or hashing when necessary.
Do not store unmasked sensitive data (full card numbers, personal identifiers, secrets) in span attributes. Use masking or tokenization to protect user data in telemetry.
Links and references

Watch Video