otel-extensions-python: OpenTelemetry Extensions for Python
OpenTelemetry Extensions for Python is a collection of helper classes, functions, and decorators to facilitate the use of the
OpenTelemetry Python API & SDK packages
Version Support
Python >= 3.6
Installation
pip install
You can install through pip using:
pip install otel-extensions
(you may need to run pip
with root permission: sudo pip install otel-extensions
)
Setuptools
Install via Setuptools.
python setup.py install --user
(or sudo python setup.py install
to install the package for all users)
Features
Tracer Provider Initialization
from otel_extensions import init_telemetry_provider, TelemetryOptions
options = TelemetryOptions(
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317/",
OTEL_EXPORTER_OTLP_CERTIFICATE="/path/to/ca/bundle",
OTEL_EXPORTER_OTLP_PROTOCOL="grpc",
OTEL_EXPORTER_CUSTOM_SPAN_EXPORTER_TYPE="pkg.ClassName",
OTEL_SERVICE_NAME="My Service",
OTEL_PROCESSOR_TYPE="batch",
TRACEPARENT="001233454656...."
)
init_telemetry_provider(options)
Instrumentation Decorator
You can use the @instrumented
decorator to automatically wrap a span around a function or method.
(As of version 0.2.0, the decorator can support coroutine functions defined as async def
as well as normal functions)
from otel_extensions import init_telemetry_provider, instrumented
import asyncio
async def main():
foo()
await async_foo()
@instrumented
def foo():
"""Creates a span named 'foo'"""
bar()
@instrumented(span_name="custom span name")
def bar():
"""Creates a span named 'custom span name'"""
print("Hello World")
@instrumented(span_attributes={"attr1": "val1", "attr2": "val2"})
def fn_with_attrs():
"""Creates a span named 'fn_with_attrs' and sets key/value pairs
from `span_attributes` as span attributes"""
print("Hello World")
@instrumented
async def async_foo():
"""Creates a span named 'async_foo'"""
await async_bar()
@instrumented(span_name="custom span name")
async def async_bar():
"""Creates a span named 'custom span name'"""
print("Hello World")
@instrumented(span_name="custom span name")
async def async_bar():
"""Creates a span named 'custom span name'"""
print("Hello World")
@instrumented(span_attributes={"attr1": "val1", "attr2": "val2"})
async def async_fn_with_attrs():
"""Creates a span named 'async_fn_with_attrs' and sets key/value pairs
from `span_attributes` as span attributes"""
print("Hello World")
if __name__ == '__main__':
init_telemetry_provider()
asyncio.run(main())
Trace Context helper class
The TraceContextCarrier
class is useful when propagating context across process or thread boundaries
from otel_extensions import TraceContextCarrier
from threading import Thread
def main_program():
...
ctx = TraceContextCarrier()
thread = Thread(thread_func, args=(ctx))
thread.start()
...
def thread_func(ctx: TraceContextCarrier):
ctx.attach()
...
Also, the TraceContextCarrier
class can attach to context stored in the TRACEPARENT
environment variable.
Note that this is done automatically when calling the init_telemetry_provider()
function.
from otel_extensions import TraceContextCarrier
TraceContextCarrier.attach_from_env()
TraceContextCarrier
can also inject the current context into the TRACEPARENT
environment variable.
This is useful for context propagation when using Popen
to create a subprocess
from otel_extensions import TraceContextCarrier
from subprocess import Popen
TraceContextCarrier.inject_to_env()
process = Popen(...)
Log messages as events
The TraceEventLogHandler
class is a logging.Handler
class that creates events for any log message that occurs in a span.
from otel_extensions import TraceEventLogHandler, init_telemetry_provider, get_tracer
import logging
init_telemetry_provider()
logging.basicConfig()
logging.getLogger(__name__).addHandler(TraceEventLogHandler())
with get_tracer(__name__).start_as_current_span("foo") as span:
logging.getLogger(__name__).warning("Some log message")