Package: otel-extensions
otel-extensions-python: OpenTelemetry Extensions for PythonOpenTelemetry Extensions for Python is a collection of helper classes, functions, and decorators to facilitate the use of theOpenTelemetry Python API & SDK packagesVersion SupportPython >= 3.6Installationpip installYou can install through pip using:pipinstallotel-extensions(you may need to runpipwith root permission:sudo pip install otel-extensions)SetuptoolsInstall viaSetuptools.pythonsetup.pyinstall--user(orsudo python setup.py installto install the package for all users)FeaturesTracer Provider Initializationfromotel_extensionsimportinit_telemetry_provider,TelemetryOptions# Provide options for telemetry provider# Alternatively, any of the following options can be specified through# environment variables with the equivalent nameoptions=TelemetryOptions(# OTLP receiver endpointOTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317/",# CA bundle for TLS verification of endpoint (if endpoint scheme is https)OTEL_EXPORTER_OTLP_CERTIFICATE="/path/to/ca/bundle",# protocol for OTLP receiver (supported: gprc | http/protobuf | custom)OTEL_EXPORTER_OTLP_PROTOCOL="grpc",# Custom span exporter class name (needed if protocol set to 'custom')OTEL_EXPORTER_CUSTOM_SPAN_EXPORTER_TYPE="pkg.ClassName",# Name of serviceOTEL_SERVICE_NAME="My Service",# Processor type#   batch:  use BatchSpanProcessor#   simple: use SimpleSpanProcessorOTEL_PROCESSOR_TYPE="batch",# Optional parent span id.  Will be injected into current contextTRACEPARENT="001233454656....")# Initialize the global tracer providerinit_telemetry_provider(options)Instrumentation DecoratorYou can use the@instrumenteddecorator to automatically wrap a span around a function or method.
(As of version 0.2.0, the decorator can support coroutine functions defined asasync defas well as normal functions)fromotel_extensionsimportinit_telemetry_provider,instrumentedimportasyncioasyncdefmain():foo()awaitasync_foo()@instrumenteddeffoo():"""Creates a span named 'foo'"""bar()@instrumented(span_name="custom span name")defbar():"""Creates a span named 'custom span name'"""print("Hello World")@instrumented(span_attributes={"attr1":"val1","attr2":"val2"})deffn_with_attrs():"""Creates a span named 'fn_with_attrs' and sets key/value pairsfrom `span_attributes` as span attributes"""print("Hello World")@instrumentedasyncdefasync_foo():"""Creates a span named 'async_foo'"""awaitasync_bar()@instrumented(span_name="custom span name")asyncdefasync_bar():"""Creates a span named 'custom span name'"""print("Hello World")@instrumented(span_name="custom span name")asyncdefasync_bar():"""Creates a span named 'custom span name'"""print("Hello World")@instrumented(span_attributes={"attr1":"val1","attr2":"val2"})asyncdefasync_fn_with_attrs():"""Creates a span named 'async_fn_with_attrs' and sets key/value pairsfrom `span_attributes` as span attributes"""print("Hello World")if__name__=='__main__':# init telemetry provider (using options from environment variables)init_telemetry_provider()asyncio.run(main())Trace Context helper classTheTraceContextCarrierclass is useful when propagating context across process or thread boundariesfromotel_extensionsimportTraceContextCarrierfromthreadingimportThreaddefmain_program():...# capture current contextctx=TraceContextCarrier()thread=Thread(thread_func,args=(ctx))thread.start()...defthread_func(ctx:TraceContextCarrier):# attach to context stored in ctxctx.attach()...Also, theTraceContextCarrierclass can attach to context stored in theTRACEPARENTenvironment variable.
Note that this is done automatically when calling theinit_telemetry_provider()function.fromotel_extensionsimportTraceContextCarrierTraceContextCarrier.attach_from_env()TraceContextCarriercan also inject the current context into theTRACEPARENTenvironment variable.
This is useful for context propagation when usingPopento create a subprocessfromotel_extensionsimportTraceContextCarrierfromsubprocessimportPopenTraceContextCarrier.inject_to_env()process=Popen(...)Log messages as eventsTheTraceEventLogHandlerclass is alogging.Handlerclass that creates events for any log message that occurs in a span.fromotel_extensionsimportTraceEventLogHandler,init_telemetry_provider,get_tracerimportlogginginit_telemetry_provider()logging.basicConfig()logging.getLogger(__name__).addHandler(TraceEventLogHandler())withget_tracer(__name__).start_as_current_span("foo")asspan:logging.getLogger(__name__).warning("Some log message")# 'Some Log message' will be created as an event in 'span',# as if you had called# span.add_event('Some Log message')