Skip to main content

opentelemetry-instrumentation-dagster

PyPI Python versions CI CodeQL License: MIT

Automatic tracing for Dagster pipelines: pip install, run your pipeline through the opentelemetry-instrument launcher, and every @op/@asset/@multi_asset/@asset_check/@dbt_assets gets a span. No @traced() decorators, no code changes, no imports in your own pipeline files at all.

Built on dagster-otel (same author) -- that project does the actual span creation via an explicit @traced() decorator; this one's only job is applying it automatically instead. See docs/design.md for why they're two separate packages rather than one.

Status (early, but verified against real infrastructure -- click to expand)

@op/@asset/@multi_asset (and @dbt_assets, which rides along on @multi_asset for free) are patched and verified against real Dagster execution, including genuine cross-process execution under both multiprocess and k8s_job_executor (a real kind cluster, dev/kubernetes/) -- both exported to a real Jaeger. @asset_check is also patched (same mechanism, verified against a real materialize() run), though not independently re-verified under multiprocess/k8s_job_executor yet. @graph_asset deliberately excluded (see What's covered). @dbt_assets not yet verified against a real dbt project end to end -- Issue #6.

Table of Contents

Installation

pip install opentelemetry-instrumentation-dagster

Quick Start

docker compose up -d brings up a local Jaeger (no other setup) so you can see a real trace land within a couple of minutes. examples/definitions.py is a plain Dagster job and asset -- zero @traced() calls, zero dagster_otel/opentelemetry imports, nothing at all:

git clone https://github.com/HirofumiTsuda/opentelemetry-instrumentation-dagster
cd opentelemetry-instrumentation-dagster
docker compose up -d

pip install opentelemetry-instrumentation-dagster
OTEL_SERVICE_NAME=quickstart \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 \
opentelemetry-instrument dagster asset materialize -f examples/definitions.py --select example_asset

Open http://localhost:16686 (Jaeger's UI), select the quickstart service, and there's the span -- example_asset, from a file that never imported this package or dagster-otel at all.

Teardown: docker compose down.

Usage

Same idea against your own pipeline: run your usual Dagster command through the opentelemetry-instrument launcher instead of running it directly.

OTEL_SERVICE_NAME=my_pipeline \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 \
opentelemetry-instrument dagster dev -f definitions.py

That's the entire setup. Every @op/@asset/@multi_asset/@asset_check/ @dbt_assets in definitions.py gets a span automatically, with no decorator, no import, no change to the file at all:

from dagster import asset, job, op

@op
def upstream_op(context) -> int:
    return 1

@op
def downstream_op(context, x: int) -> int:
    return x + 1

@asset
def my_asset(context) -> None:
    ...

@job
def my_job():
    downstream_op(upstream_op())

The launcher works the same way in front of dagster job execute, dagster-webserver, dagster-daemon, or any other Dagster entry point -- it's a drop-in prefix, not something specific to dagster dev.

What's covered

Decorator Status
@op ✅ Patched -- bare and @op(name=...) forms
@asset ✅ Patched -- bare and @asset(name=...) forms
@multi_asset ✅ Patched
@asset_check ✅ Patched -- @asset_check(asset=...) and @asset_check(asset=..., name=...) forms. Requires dagster-otel >= 0.4.0 (its AssetCheckExecutionContext support).
@dbt_assets (dagster_dbt) ✅ Covered for free -- it calls multi_asset internally, see docs/design.md. One span per dbt run (not dagster-otel's finer per-model @traced_dbt() granularity) -- Issue #6 tracks verifying this against a real dbt project end to end.
@graph_asset ⬜ Deliberately not patched -- its decorated function never receives a runtime context at all, so @traced() doesn't apply to it. Tracing the ops it composes (which already works, no changes needed) already covers everything that actually executes. See docs/design.md.

Configuration

Same standard OTel environment variables dagster-otel itself reads -- nothing this package adds on top:

Variable Purpose
OTEL_SERVICE_NAME Names your service in the trace backend.
OTEL_EXPORTER_OTLP_ENDPOINT (or ..._TRACES_ENDPOINT) Where to send spans (e.g. http://localhost:4317). Required -- without one of these set, no real exporter is attached at all.
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL / ..._PROTOCOL Transport to export over: grpc (default) or http/protobuf.
OTEL_SDK_DISABLED Set to true to force no export regardless of the endpoint vars above.

See dagster-otel's own README for the full list and what each one actually does underneath -- this package doesn't wrap or reinterpret any of it, just triggers the same traced() that reads these itself.

multiprocess/k8s_job_executor

Each step in a multiprocess-executed run runs in its own, freshly spawned Python interpreter -- the opentelemetry-instrument launcher above already handles this correctly (verified against a real run, see docs/design.md), no extra setup needed.

k8s_job_executor is different: each step becomes a genuinely separate Kubernetes Pod, and the launcher's usual mechanism can't propagate into a brand new container the way it does into a spawned OS subprocess. This needs the instrumentation baked into the container image itself instead -- no opentelemetry-instrument prefix anywhere, because nothing in your own config controls the command k8s_job_executor constructs internally for each step Pod.

Using this with k8s_job_executor

In your own Dockerfile, after installing this package, copy opentelemetry-instrumentation's real sitecustomize.py into your venv's site-packages root:

RUN site_packages="$(python -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')" && \
    cp "$site_packages/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py" \
       "$site_packages/sitecustomize.py"

Python auto-imports any module literally named sitecustomize found directly in site-packages at interpreter startup -- so this alone is enough, in every container built from that image, including every step Pod k8s_job_executor launches from it. No PYTHONPATH, no .pth file, no launcher prefix anywhere in your run config or Dockerfile CMD.

(If your build process makes a sysconfig-based path awkward -- e.g. a venv at a path you already know ahead of time -- find /path/to/venv -maxdepth 4 -type d -name site-packages works just as well. Setting PYTHONPATH explicitly via k8s_job_executor's env_vars run config is an alternative to copying the file at all, if that fits your deployment better.)

dev/kubernetes/ is a complete, real-cluster-verified example of this exact pattern (Dockerfile, kind manifests, RBAC) -- written as this project's own verification harness, not a copy-paste-ready deployment template, but the Dockerfile's approach is the same one described above. See docs/design.md for the full reasoning and the negative-control verification.

Compatibility

Depends on dagster-otel and dagster >= 1.5, same floor as that project. Not independently version-matrix-tested beyond what dagster-otel itself covers -- if you hit an incompatibility, open an issue.

Why a separate package

dagster-otel's whole pitch is tracing without monkeypatching Dagster internals and without taking ownership of your op/asset definitions away from you. Auto-instrumentation is the opposite trade: zero code changes, in exchange for some framework patching and losing that per-function visibility. Both are legitimate, but they're different products for different people -- same split the OpenTelemetry Python ecosystem itself uses (opentelemetry-instrumentation-flask, -django, etc. are all separate packages from the manual API/SDK). See docs/design.md for the full reasoning.

Contributing

Issues and PRs welcome -- open an issue for bugs, missing coverage, or a backend that doesn't work as expected.

License

MIT

Release files for opentelemetry-instrumentation-dagster 0.2.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-dagster 0.2.0
File Size Uploaded
opentelemetry_instrumentation_dagster-0.2.0.tar.gz 307.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for opentelemetry-instrumentation-dagster 0.2.0
File Interpreter ABI Platform
opentelemetry_instrumentation_dagster-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 316.6 kB

Release files / opentelemetry_instrumentation_dagster-0.2.0.tar.gz

Download URL opentelemetry_instrumentation_dagster-0.2.0.tar.gz
Size 307.0 kB
Tags Source
SHA-256 checksum
How to use checksums
206795d543a0fb5b2f0d43b5de42b057cbf810183a9906e0a6920e1c2d925f53
BLAKE2b-256 checksum
How to use checksums
b0e6445a99067d3e2355ae1a8b5b334dca76198f24230ed9dba44b6e588b05b2
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 Sep 22, 2026.

Transparency log

Release files / opentelemetry_instrumentation_dagster-0.2.0-py3-none-any.whl

Download URL opentelemetry_instrumentation_dagster-0.2.0-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
92df5ad32a6d0ef87813974b3cbc29ffaa8f55ae5b5b0e6f45fa3f674391d70a
BLAKE2b-256 checksum
How to use checksums
69d6133a8b614771fd15d2dcab73644e9d3bd9380d443ae62f5048e18417e19c
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 Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

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