OpenTelemetry-native async context propagation for asyncio
Project description
aiotrace – Async context propagation for OpenTelemetry
Fixes OpenTelemetry context propagation across asyncio boundaries:
create_task, Queue, Lock, Event, Semaphore, TaskGroup, and
run_in_executor (thread pool).
Problem
OpenTelemetry stores the current span in a contextvars.ContextVar.
When asyncio tasks are created or resumed, Python copies/shallow-copies
these contextvars. On Python < 3.9.17 / 3.10.7 / 3.11.1, Task.__step
does not restore the task's own context, causing:
- Spans created in child tasks appearing under the wrong parent
- Context leaking between producer/consumer queues
- Lost context when using
run_in_executor(threads)
Quick Start
import asyncio
from opentelemetry import trace
from aiotrace import install
install()
tracer = trace.get_tracer(__name__)
async def child():
with tracer.start_as_current_span("child"):
pass
async def main():
with tracer.start_as_current_span("parent"):
await asyncio.create_task(child())
asyncio.run(main())
Manual Usage (no monkey-patching)
from aiotrace import create_task_with_context, PropagatingQueue
# Use explicit wrapper instead of monkey-patch
task = create_task_with_context(some_coro())
# Explicit propagating queue
queue = PropagatingQueue()
await queue.put(item)
item = await queue.get()
Installation
pip install aiotrace
What Gets Patched
| Primitive | Replacement | Description |
|---|---|---|
asyncio.create_task |
Wrapped | Captures OTEL context at task creation, restores inside child |
asyncio.Queue |
PropagatingQueue |
Re-attaches context after get()/put() resume |
asyncio.Lock |
PropagatingLock |
Re-attaches context after acquire() |
asyncio.Event |
PropagatingEvent |
Re-attaches context after wait() |
asyncio.Semaphore |
PropagatingSemaphore |
Re-attaches context after acquire() |
asyncio.Condition |
PropagatingCondition |
Re-attaches context after wait() |
asyncio.TaskGroup (3.11+) |
PropagatingTaskGroup |
Captures context at create_task() |
API
install(patch_queue=True, patch_locks=True)
Monkey-patches asyncio primitives. Safe to call multiple times (idempotent).
uninstall()
Restores original asyncio primitives.
PropagatingQueue(maxsize=0)
Drop-in replacement for asyncio.Queue with context propagation.
PropagatingLock, PropagatingEvent, PropagatingSemaphore, PropagatingCondition
Drop-in replacements for synchronization primitives.
create_task_with_context(coro, *, name=None, otel_ctx=None)
Create a task with explicit OTEL context propagation.
run_in_executor_with_context(executor, func, *args)
Schedule a function in a thread pool with OTEL context.
Requirements
- Python 3.8–3.12
opentelemetry-api >= 1.20.0
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiotrace-0.1.0.tar.gz.
File metadata
- Download URL: aiotrace-0.1.0.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdb1253c849667952a06b1c90c47f3656af3b92d08ad10e14d4518fd2e1b547e
|
|
| MD5 |
25e2078cbc4851356a1737c84a7981bc
|
|
| BLAKE2b-256 |
bf27a790ada048e14952be4f6f057559b217ee2a194c8686989379c656f51c55
|
File details
Details for the file aiotrace-0.1.0-py2.py3-none-any.whl.
File metadata
- Download URL: aiotrace-0.1.0-py2.py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be210b345075d0afdcf28824124b3e0d0d90316aa4d07d56303e98b65247b410
|
|
| MD5 |
58644f03b260e8b63462b42c3256d8b5
|
|
| BLAKE2b-256 |
8c76e250054c8f7972094a653902ff1bd1a8f0b9fa4d0a4ff5deb5e94d61e9dc
|