Manual Instrumentation
Manual instrumentation is the process of adding observability code to your application.
Initializing the SDK¶
First, ensure you have the API and SDK packages:
To start tracing, you'll need to initialize a
TracerProvider
and
optionally set it as the global default.
To start collecting metrics, you'll need to initialize a
MeterProvider
and optionally
set it as the global default.
Tracing¶
Creating spans¶
To create a span, you'll typically want it to be started as the current span.
You can also use start_span
to create a span without making it the current
span. This is usually done to track concurrent or asynchronous operations.
Creating nested spans¶
If you have a distinct sub-operation you'd like to track as a part of another one, you can create spans to represent the relationship:
When you view spans in a trace visualization tool, child
will be tracked as a
nested span under parent
.
Creating spans with decorators¶
It's common to have a single span track the execution of an entire function. In that scenario, there is a decorator you can use to reduce code:
Use of the decorator is equivalent to creating the span inside do_work()
and
ending it when do_work()
is finished.
To use the decorator, you must have a tracer
instance available global to your
function declaration.
If you need to add attributes, events, or links then it's less convenient to use a decorator.
Get the current span¶
Sometimes it's helpful to access whatever the current span is at a point in time so that you can enrich it with more information.
Add attributes to a span¶
Attributes let you attach key/value pairs to a span so it carries more information about the current operation that it's tracking.
Add semantic attributes¶
Semantic Attributes are pre-defined Attributes that are well-known naming conventions for common kinds of data. Using Semantic Attributes lets you normalize this kind of information across your systems.
To use Semantic Attributes in Python, ensure you have the semantic conventions package:
Then you can use it in code:
Adding events¶
An event is a human-readable message on a span that represents "something happening" during its lifetime. You can think of it as a primitive log.
Adding links¶
A span can be created with zero or more span links that causally link it to another span. A link needs a span context to be created.
Set span status¶
A status can be set on a
span, typically used to specify that a
span has not completed successfully - StatusCode.ERROR
. In rare scenarios, you
could override the Error status with StatusCode.OK
, but don’t set
StatusCode.OK
on successfully-completed spans.
The status can be set at any time before the span is finished:
Record exceptions in spans¶
It can be a good idea to record exceptions when they happen. It’s recommended to do this in conjunction with setting span status.
Change the default propagation format¶
By default, OpenTelemetry Python will use the following propagation formats:
- W3C Trace Context
- W3C Baggage
If you have a need to change the defaults, you can do so either via environment variables or in code:
Using Environment Variables¶
You can set the OTEL_PROPAGATORS
environment variable with a comma-separated
list. Accepted values are:
"tracecontext"
: W3C Trace Context"baggage"
: W3C Baggage"b3"
: B3 Single"b3multi"
: B3 Multi"jaeger"
: Jaeger"xray"
: AWS X-Ray (third party)"ottrace"
: OT Trace (third party)"none"
: No automatically configured propagator.
The default configuration is equivalent to
OTEL_PROPAGATORS="tracecontext,baggage"
.
Using SDK APIs¶
Alternatively, you can change the format in code.
For example, if you need to use Zipkin's B3 propagation format instead, you can install the B3 package:
And then set the B3 propagator in your tracing initialization code:
Note that environment variables will override what's configured in code.
Metrics¶
Creating and using synchronous instruments¶
Instruments are used to make measurements of your application. Synchronous instruments are used inline with application/business processing logic, like when handling a request or calling another service.
First, create your instrument. Instruments are generally created once at the module or class level and then used inline with business logic. This example uses a Counter instrument to count the number of work items completed:
Using the Counter's add operation, the code below increments the count by one, using the work item's type as an attribute.
Creating and using asynchronous instruments¶
Asynchronous instruments give the user a way to register callback functions, which are invoked on demand to make measurements. This is useful to periodically measure a value that cannot be instrumented directly. Async instruments are created with zero or more callbacks which will be invoked during metric collection. Each callback accepts options from the SDK and returns its observations.
This example uses an Asynchronous Gauge instrument to report the current config version provided by a configuration server by scraping an HTTP endpoint. First, write a callback to make observations:
Note that OpenTelemetry will pass options to your callback containing a timeout. Callbacks should respect this timeout to avoid blocking indefinitely. Finally, create the instrument with the callback to register it: