OpenTelemetry Tracing API for Python
TIP
This document teaches how to use OpenTelemetry Python API. To learn how to install and configure OpenTelemetry Python SDK, see Getting started with OpenTelemetry Python .
Installation
OpenTelemetry-Python is the Python implementation of OpenTelemetry. It provides OpenTelemetry Tracing API which you can use to instrument your application with OpenTelemetry tracing .
pip install opentelemetry-api
Quickstart
Step 1 . Let's instrument the following function:
def insert_user(**kwargs):
return User.objects.create_user(**kwargs)
Step 2 . Wrap the operation with a span :
from opentelemetry import trace
tracer = trace.get_tracer("app_or_package_name", "1.0.0")
def insert_user(**kwargs):
with tracer.start_as_current_span("insert-user") as span:
return User.objects.create_user(**kwargs)
Step 3 . Record contextual information with attributes :
def insert_user(**kwargs):
with tracer.start_as_current_span("insert-user") as span:
if span.is_recording():
span.set_attribute("enduser.id", kwargs["id"])
span.set_attribute("enduser.email", kwargs["email"])
return User.objects.create_user(**kwargs)
And that's it! You don't have to manually record exceptions, because
tracer.start_as_current_span
does that automatically for you.
Tracer
To start creating spans , you need a tracer. You can create a tracer by providing the name and version of the library/application doing the instrumentation:
from opentelemetry import trace
tracer = trace.get_tracer("app_or_package_name", "1.0.0")
You can have as many tracers as you want, but usually you need only one tracer for an app or a library. Later, you can use tracer names to identify the instrumentation that produces the spans.
Creating spans
Once you have a tracer, creating spans is easy:
# Create a span with name "operation-name" and kind="server".
with tracer.start_as_current_span("operation-name", kind=trace.SpanKind.SERVER) as span:
do_some_work()
Adding span attributes
To record contextual information, you can annotate spans with
attributes
. For example, an HTTP endpoint may have such attributes as
http.method = GET
and
http.route = /projects/:id
.
# To avoid expensive computations, check that span is recording
# before setting any attributes.
if span.is_recording():
span.set_attribute("http.method", "GET")
span.set_attribute("http.route", "/projects/:id")
You can name attributes as you want, but for common operations you should use semantic attributes convention.
Adding span events
You can annotate spans with events , for example, you can use events to record log messages:
span.add_event("log", {
"log.severity": "error",
"log.message": "User not found",
"enduser.id": "123",
Setting status code
You can set
error
status code
to indicate that the operation contains an error:
except ValueError as exc:
span.set_status(trace.Status(trace.StatusCode.ERROR, str(exc)))
Recording exceptions
OpenTelemetry provides a shortcut to record exceptions which is usually used together with
set_status
:
except ValueError as exc:
# Record the exception and update the span status.
span.record_exception(exc)
span.set_status(trace.Status(trace.StatusCode.ERROR, str(exc)))
Context
OpenTelemetry stores the active span in a context and saves the context in a thread-local storage. You can nest contexts inside each other and OpenTelemetry will automatically activate the parent span context when you end the span.
start_as_current_span
sets the active span for you, but you can also activate the span manually:
# Activate the span in the current context.
with trace.use_span(span, end_on_exit=True):
do_some_work()
To get the active span from the current context:
from opentelemetry import trace
span = trace.get_current_span()
If you are using distributed services, you can propagate context to another service using OpenTelemetry requests instrumentation .
Auto-instrumentation
TIP
When possible, you should prefer using explicit instrumentation, for example, auto-instrumentation does not work well with Flask in debug mode.
opentelemetry-python allows you to automatically instrument any Python app using
opentelemetry-instrument
utility from
opentelemetry-instrumentation
package.
First, you need to install the
opentelemetry-instrument
executable:
pip install opentelemetry-instrumentation