OpenTelemetry Python Extensions
OpenTelemetry Extensions for Python is a collection of helper classes, functions, and decorators designed to simplify the use of the OpenTelemetry Python API and SDK packages. It currently supports Python >= 3.8 and is actively maintained, with version 1.1.0 released in October 2024.
Common errors
-
ModuleNotFoundError: No module named 'otel_extensions'
cause The `otel-extensions` package has not been installed in the current Python environment.fixRun `pip install otel-extensions` to install the library. -
Telemetry data is not appearing in my backend (e.g., Jaeger, Prometheus, OTLP Collector).
cause This is typically caused by incorrect configuration of the exporter endpoint, service name, or processor type, or the OpenTelemetry Collector/backend not running or being inaccessible.fixVerify that `OTEL_EXPORTER_OTLP_ENDPOINT` (or equivalent for other exporters) is correctly set to your collector/backend address and port (e.g., `http://localhost:4317/`). Ensure `OTEL_SERVICE_NAME` is set for proper identification. Check that the OpenTelemetry Collector or your chosen backend is running and reachable. Also, confirm that `init_telemetry_provider()` is called early in your application's lifecycle. -
Trace context is not propagated across threads or processes.
cause Python's threading and multiprocessing models often require explicit context management for OpenTelemetry traces.fixUse the `TraceContextCarrier` class provided by `otel-extensions` to capture and attach trace context when spawning new threads or processes. -
Instrumentation decorator (`@instrumented`) is not creating spans.
cause This can happen if the global tracer provider is not initialized before the decorated function is called, or if environment variables like `OTEL_PROCESS_MODULES` are restricting instrumentation.fixEnsure `init_telemetry_provider()` is called at the very beginning of your application. Check if `OTEL_PROCESS_MODULES` environment variable is set and if the module containing the decorated function is included in its list, if applicable.
Warnings
- gotcha The `otel-extensions` library (and core OpenTelemetry Python) requires Python >= 3.8. Using older Python versions may lead to unexpected behavior or lack of support.
- breaking OpenTelemetry Python is undergoing a migration to stable semantic conventions, particularly for HTTP-related instrumentations. This could change attribute names or data structures, requiring updates to consuming systems or custom code that relies on specific semantic attributes.
- deprecated Jaeger exporters have been deprecated in the core OpenTelemetry Python SDK. If `otel-extensions` previously provided helpers for Jaeger, these might become non-functional or removed in future versions.
- gotcha Many instrumentation packages within the `opentelemetry-python-contrib` repository, which `otel-extensions` may implicitly rely on or complement, are still in 'beta' status. They are generally not recommended for production environments without thorough testing.
Install
-
pip install otel-extensions
Imports
- init_telemetry_provider
from otel_extensions import init_telemetry_provider
- TelemetryOptions
from otel_extensions import TelemetryOptions
- @instrumented
from otel_extensions import instrumented
- TraceContextCarrier
from otel_extensions import TraceContextCarrier
- TraceEventLogHandler
from otel_extensions import TraceEventLogHandler
Quickstart
import os
from otel_extensions import init_telemetry_provider, TelemetryOptions
from opentelemetry import trace
# Configure telemetry options, can also be set via environment variables
options = TelemetryOptions(
OTEL_EXPORTER_OTLP_ENDPOINT=os.environ.get('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4317/'),
OTEL_EXPORTER_OTLP_PROTOCOL=os.environ.get('OTEL_EXPORTER_OTLP_PROTOCOL', 'grpc'),
OTEL_SERVICE_NAME=os.environ.get('OTEL_SERVICE_NAME', 'my-service'),
OTEL_PROCESSOR_TYPE=os.environ.get('OTEL_PROCESSOR_TYPE', 'batch')
)
# Initialize the global tracer provider
init_telemetry_provider(options)
# Get a tracer and create a span
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("example-operation") as span:
span.set_attribute("custom.attribute", "example_value")
print("Performing an example operation with tracing...")
print("Telemetry provider initialized and example span created.")