Skip to main content

opentelemetry-instrumentation-absurd

Tests PyPI Python versions License: MIT

OpenTelemetry instrumentation for the Absurd durable-task SDK (absurd-sdk).

Absurd (absurd_sdk.AsyncAbsurd) is a Postgres-backed durable task queue: a producer spawn()s a task and a worker work_batch() claims and runs the registered handler, possibly in a different process. Without instrumentation the two halves live in separate traces, so a task's execution cannot be linked back to whatever spawned it.

This instrumentor follows the standard producer/consumer span shape for a task queue:

  • AsyncAbsurd.spawn() is wrapped to open a CLIENT span named after the task and inject the current trace context into the task's headers. Absurd persists headers on the task row and hands them back to the handler via ctx.headers.
  • AsyncAbsurd.register_task() is wrapped so every registered handler runs inside a running:<task> SERVER span whose parent is extracted from those headers.

The two spans share one trace, so a task's execution is linked back to whatever spawned it — even when the spawner and the worker run in different processes.

trigger (your span)
└── report                 CLIENT   ← spawn()  (process A)
    └── running:report     SERVER   ← handler  (process B)

Installation

pip install opentelemetry-instrumentation-absurd
# or
uv add opentelemetry-instrumentation-absurd

Usage

Install the instrumentor once per process, on both the spawn side and the worker side:

from opentelemetry.instrumentation.absurd import AbsurdInstrumentor

AbsurdInstrumentor().instrument()

That is all — no changes to your spawn() calls or task handlers are required. Only AsyncAbsurd is instrumented.

You can pass an explicit TracerProvider:

AbsurdInstrumentor().instrument(tracer_provider=my_tracer_provider)

Because this package ships an opentelemetry_instrumentor entry point, it is also picked up automatically by opentelemetry-instrument:

opentelemetry-instrument python your_app.py

Producer / consumer example

import asyncio

from absurd_sdk import AsyncAbsurd
from opentelemetry.instrumentation.absurd import AbsurdInstrumentor

AbsurdInstrumentor().instrument()

app = AsyncAbsurd('postgresql://localhost/absurd', queue_name='workflows')


@app.register_task(name='report')
async def report(params, ctx):
    # Runs inside a `running:report` SERVER span parented to the spawner.
    return {'value': params['value'] * 2}


async def main() -> None:
    # Opens a `report` CLIENT span and injects the trace context into the task headers.
    await app.spawn('report', {'value': 7}, queue='workflows')


asyncio.run(main())

Span attributes

Both spans carry these attributes (set when available):

Attribute Span Description
absurd.task.name CLIENT + SERVER The registered task name.
absurd.queue CLIENT + SERVER The queue the task was spawned on.
absurd.task.id CLIENT + SERVER The task UUID (stringified).
absurd.run.id CLIENT The run UUID assigned by spawn().
absurd.task.attempt SERVER The current attempt number of the run.
absurd.task.idempotency_key CLIENT Set only when an idempotency key is given.

The trace context is propagated through the task headers under the otel.absurd.context key using the globally configured OpenTelemetry propagator (W3C traceparent by default), so any caller headers you pass are preserved.

How it works

spawn() and the registered handler are wrapped with wrapt. On spawn() the current context is injected into a fresh carrier nested under a single header key; the worker extracts that carrier and parents its SERVER span to the spawner's CLIENT span. If a task was spawned before instrumentation (no carrier present), the handler still runs in its own SERVER span — it just starts a new trace.

Compatibility

  • Python 3.10+
  • absurd-sdk >= 0.4.0
  • opentelemetry-api >= 1.0

Development

make install   # uv sync --all-groups
make test      # uv run pytest
make check     # ruff check + ruff format --check

AI disclaimer

This code was written with the help of AI.

License

MIT

Metadata

Release files for opentelemetry-instrumentation-absurd 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for opentelemetry-instrumentation-absurd 0.1.0
File Size Uploaded
opentelemetry_instrumentation_absurd-0.1.0.tar.gz 6.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for opentelemetry-instrumentation-absurd 0.1.0
File Interpreter ABI Platform
opentelemetry_instrumentation_absurd-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.8 kB

Release files / opentelemetry_instrumentation_absurd-0.1.0.tar.gz

Download URL opentelemetry_instrumentation_absurd-0.1.0.tar.gz
Size 6.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6c5086707b0c24e1d53c562134504db8fbe8454476ca4ecfb27fe2829a644d3f
BLAKE2b-256 checksum
How to use checksums
743484b4ccdb2d00a905b044e4a6acaf25efbd40de314c8b8047a7757979d1b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log

Release files / opentelemetry_instrumentation_absurd-0.1.0-py3-none-any.whl

Download URL opentelemetry_instrumentation_absurd-0.1.0-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8df44d213a3e8248a3e7b7ac192936bd43516ddf43d5a0fc4a85b78153652ece
BLAKE2b-256 checksum
How to use checksums
9ec7ffd1454d1bd1899061531096c159c9f0509bafcedd78104772de00505d0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page