A lightweight Celery task flow visualizer
Project description
stemtrace ๐ฟ
Zero-infrastructure Celery task flow visualizer
Flower shows you what exists. Stemtrace shows you what happened.
Ever stared at a failed Celery task wondering "what called this?" or "why did it retry 5 times?"
Stemtrace captures your task executions as a graph โ visualize parentโchild flows, see retry chains, track groups and chords, all without adding any new infrastructure.
Today stemtrace supports Redis for event transport (via Redis Streams). RabbitMQ support is planned.
โจ Features
See What Happened
- Task Flow Graphs โ Visualize chains, groups, and chords as interactive DAGs
- Execution Timeline โ Track queued โ started โ retried โ finished states
- Arguments & Results โ Inspect inputs, outputs, and exceptions
- Retry Chains โ Understand exactly when and why retries happened
Canvas Support
- Groups & Chords โ Automatic visualization of
group()andchord()patterns - Parent-Child Tracking โ See which task spawned which
Worker Monitoring & Registry
- Workers page โ See which workers are online/offline and what tasks they have registered
- Registry status badges โ Quickly spot tasks that are active, never run, or not registered by any current worker
Production Ready
- Zero Infrastructure โ Uses your existing Redis broker, no database needed
- Sensitive Data Scrubbing โ Passwords and API keys filtered automatically
- Read-Only โ Safe for production; never modifies your task queue
- FastAPI Integration โ Mount into your existing app with one line
๐ What youโll see in the dashboard
Task details (timing, inputs/outputs, errors)
- What youโll see: Per-task execution timing (including how long it spent in each state), parameters (args/kwargs), return value, and the full event history.
- Why it helps: Quickly answer โwhat happened?โ for a single task: slow queueing vs slow execution, which retry succeeded, and (on failures) the exception + traceback for debugging.
Flow graphs (chains, groups, chords)
- What youโll see: An interactive DAG of your workflow with parentโchild edges, plus clear GROUP/CHORD containers for Celery canvas patterns.
- Why it helps: Understand fan-out/fan-in at a glance (especially chords), spot which branch failed, and debug โwhy didnโt my callback run?โ without grepping logs.
Task registry (registration status + warnings)
- What youโll see: A registry of tasks with status badges like Active, Never Run, and Not Registered plus โregistered by โฆโ worker info.
- Why it helps: Catch misconfigurations where tasks get stuck in PENDING because no current worker has the task registered (common in multi-repo or deploy drift scenarios).
๐ Quick Start
1. Install
# Using pip
pip install stemtrace
# Using uv
uv add stemtrace
2. Instrument your Celery app
from celery import Celery
import stemtrace
app = Celery("myapp", broker="redis://localhost:6379/0")
# One line to enable event capture.
# Tip: put this in the module where you define your Celery app so it's imported by
# both Celery workers and any code that calls app.send_task()/delay().
stemtrace.init_worker(app)
3. View the dashboard
Option A: Standalone server (new container/process)
stemtrace server
Open http://localhost:8000.
Option B: Embed in your FastAPI app (no extra container)
from fastapi import FastAPI
import stemtrace
app = FastAPI(lifespan=my_lifespan) # Your existing app
stemtrace.init_app(app, broker_url="redis://localhost:6379/0")
Access at /stemtrace/ in your existing app โ no new services to deploy.
See Deployment Options for auth, scaling, and more.
๐ฆ Architecture
stemtrace is designed as two decoupled components:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Celery Workerโ โ Celery Workerโ โ Celery Workerโ โ
โ โ + stemtrace โ โ + stemtrace โ โ + stemtrace โ โ
โ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ โ
โ โ events โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโ โ
โ โ Broker โ โ
โ โโโโโโโโโฌโโโโโโโโ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโ
โ stemtrace โ
โ server (viewer) โ
โ โโโโโโโโโโโโโโโ โ
โ โ Web UI โ โ
โ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโ
Library (stemtrace)
- Hooks into Celery signals
- Captures task lifecycle events
- Sends normalized events to the broker
- Zero overhead in critical path โ fire-and-forget writes
Server (stemtrace server)
- Reads events from the broker
- Builds task graphs
- Serves the web UI
- Completely read-only โ safe for production
๐ง Configuration
Library Options
import stemtrace
stemtrace.init_worker(
app,
# Optional: override broker URL (defaults to Celery's broker_url)
transport_url="redis://localhost:6379/0",
prefix="stemtrace", # Key/queue prefix
ttl=86400, # Event TTL in seconds (default: 24h)
# Data capture (all enabled by default)
capture_args=True, # Capture task args/kwargs
capture_result=True, # Capture return values
# Sensitive data scrubbing (Sentry-style)
scrub_sensitive_data=True, # Scrub passwords, API keys, etc.
additional_sensitive_keys=frozenset({"my_secret"}), # Add custom keys
safe_keys=frozenset({"public_key"}), # Never scrub these keys
)
# Introspection (after init)
stemtrace.is_initialized() # -> True
stemtrace.get_config() # -> StemtraceConfig
stemtrace.get_transport() # -> EventTransport (for testing)
Sensitive Data Scrubbing
By default, stemtrace scrubs common sensitive keys from task arguments:
- Passwords:
password,passwd,pwd,secret - API keys:
api_key,apikey,token,bearer,authorization - Financial:
credit_card,cvv,ssn - Session:
cookie,session,csrf
Scrubbed values appear as [Filtered] in the UI.
Canvas Graph Visualization
stemtrace automatically detects and visualizes Celery canvas constructs:
# Parent-spawned group: GROUP is child of parent
batch_processor
โโโ โโ GROUP โโโโโโโโโโโ
โ โโโ add(1, 2) โ
โ โโโ add(3, 4) โ
โ โโโ add(5, 6) โ
โโโโโโโโโโโโโโโโโโโโ
# Standalone group: GROUP is a root node
โโ GROUP โโโโโโโโโโโ
โ โโโ add(1, 1) โ
โ โโโ add(2, 2) โ
โ โโโ add(3, 3) โ
โโโโโโโโโโโโโโโโโโโโ
# Chord: header tasks inside, callback outside with edges
โโ CHORD โโโโโโโโโโโ
โ โโโ add(10, 10) โโโโ
โ โโโ add(20, 20) โโโโผโโโบ aggregate_results
โ โโโ add(30, 30) โโโโ
โโโโโโโโโโโโโโโโโโโโ
- Synthetic containers โ GROUP/CHORD nodes are always created when 2+ tasks share a
group_id - Parent linking โ When spawned from a parent task, the container becomes a child of that parent
- Chord callbacks โ Rendered outside the container with edges from each header task
- Timing โ Each node displays start time and duration directly in the graph
- Aggregate state โ Container shows running/success/failure based on member states
Environment Variables
| Variable | Description | Default |
|---|---|---|
STEMTRACE_BROKER_URL |
Broker URL for stemtrace server / stemtrace consume and stemtrace.init_app() |
redis://localhost:6379/0 |
Supported Brokers
| Broker | URL Scheme | Status |
|---|---|---|
| Redis | redis://, rediss:// |
โ Supported |
| RabbitMQ | amqp://, amqps:// |
๐ง Planned |
๐ณ Docker
docker run -p 8000:8000 \
-e STEMTRACE_BROKER_URL=redis://host.docker.internal:6379/0 \
ghcr.io/iansokolskyi/stemtrace
Or with Docker Compose:
services:
stemtrace:
image: ghcr.io/iansokolskyi/stemtrace
ports:
- "8000:8000"
environment:
- STEMTRACE_BROKER_URL=redis://redis:6379/0
๐ฅ๏ธ Deployment Options
stemtrace offers two deployment modes depending on your needs:
| Mode | Best For | Command |
|---|---|---|
| Standalone Server | Dedicated monitoring, simple setup | stemtrace server |
| FastAPI Embedded | Single-app deployment, existing FastAPI apps | stemtrace.init_app(...) |
Option 1: Standalone Server (Recommended)
The simplest way to run stemtrace โ a dedicated monitoring service:
pip install stemtrace
stemtrace server
Open http://localhost:8000 to view the dashboard.
Server Options
stemtrace server \
--broker-url redis://myredis:6379/0 \
--host 0.0.0.0 \
--port 8000 \
--reload # For development
High-Scale Production Setup
Note: stemtrace server includes an embedded consumer today (single-process). A multi-process deployment mode is planned.
Option 2: FastAPI Embedded
Mount stemtrace directly into your existing FastAPI application:
from fastapi import FastAPI
import stemtrace
app = FastAPI(lifespan=my_lifespan) # Your existing app with lifespan
stemtrace.init_app(app, broker_url="redis://localhost:6379/0") # Wraps lifespan, adds /stemtrace routes
That's it. init_app() automatically:
- Wraps your existing lifespan (Sentry, DB connections, etc. keep working)
- Mounts the dashboard at
/stemtrace/ - Starts the event consumer
Configuration Options
import stemtrace
# Returns the underlying StemtraceExtension if you need it (optional).
extension = stemtrace.init_app(
app,
broker_url="redis://localhost:6379/0",
prefix="/stemtrace", # Mount path AND event stream prefix (normalized)
ttl=86400, # Event TTL in seconds
max_nodes=10000, # Max nodes in memory
embedded_consumer=True, # Run consumer in FastAPI process
serve_ui=True, # Serve React dashboard
auth_dependency=None, # Optional auth (see below)
)
With Custom Authentication
from fastapi import Depends
import stemtrace
from your_app.auth import require_admin
stemtrace.init_app(app, broker_url="redis://localhost:6379/0", auth_dependency=Depends(require_admin))
Or use built-in auth helpers:
import stemtrace
stemtrace.init_app(
app,
broker_url="redis://localhost:6379/0",
auth_dependency=stemtrace.require_basic_auth("admin", "secret"),
)
Embedded Consumer Modes
| Mode | Use Case | Setup |
|---|---|---|
| Embedded | Development, simple apps | Default โ consumer runs in FastAPI process |
| External | Production, high scale | Planned |
๐บ๏ธ Roadmap
What's Working Now
- โ Task flow graphs โ Visualize chains, groups, and chords as DAGs
- โ Full lifecycle tracking โ PENDING โ RECEIVED โ STARTED โ SUCCESS/FAILURE
- โ Canvas awareness โ Automatic GROUP/CHORD node visualization
- โ Arguments & results โ View inputs, outputs, and exceptions
- โ Sensitive data scrubbing โ Passwords and API keys filtered automatically
- โ Real-time updates โ WebSocket-powered live dashboard
- โ FastAPI integration โ Mount into your existing app
- โ Workers page โ Monitor online/offline workers and their registered tasks
- โ Task registry โ Browse discovered + registered tasks with clear status badges
Coming Soon
- ๐ RabbitMQ support โ Use your existing RabbitMQ broker
- ๐ Anomaly detection โ Spot stuck, orphaned, or failed tasks
- ๐ Dashboard with stats โ Success rates, durations, failure trends
- ๐ OpenTelemetry export โ Send traces to Jaeger, Tempo, Datadog
- ๐ Webhook notifications โ Push events to your systems
- ๐ Data export โ Download execution history as JSON
๐ค Contributing
Contributions, bug reports, and feature requests are welcome! This is a community project โ if stemtrace helps you debug Celery, consider helping make it better.
See our Contributing Guide to get started.
git clone https://github.com/iansokolskyi/stemtrace.git
cd stemtrace
uv sync --extra dev # Install dependencies
make check # Run tests
๐ License
MIT โ use it however you like.
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 stemtrace-0.2.1.tar.gz.
File metadata
- Download URL: stemtrace-0.2.1.tar.gz
- Upload date:
- Size: 866.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e484df2a1cf481dfd889124395f30d0a144449acda4828c523f3dd2a8f29788
|
|
| MD5 |
9616a648b4f0b598727f360bce0afbb7
|
|
| BLAKE2b-256 |
399ee5e6486ce6e13631b6a77fcdfd0a6b706d57ed75437d666c4a26503cbe63
|
Provenance
The following attestation bundles were made for stemtrace-0.2.1.tar.gz:
Publisher:
release.yml on iansokolskyi/stemtrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stemtrace-0.2.1.tar.gz -
Subject digest:
0e484df2a1cf481dfd889124395f30d0a144449acda4828c523f3dd2a8f29788 - Sigstore transparency entry: 789746857
- Sigstore integration time:
-
Permalink:
iansokolskyi/stemtrace@75beb6928da0a0f102afc50cc4d412ea7ab7b8ac -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/iansokolskyi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@75beb6928da0a0f102afc50cc4d412ea7ab7b8ac -
Trigger Event:
push
-
Statement type:
File details
Details for the file stemtrace-0.2.1-py3-none-any.whl.
File metadata
- Download URL: stemtrace-0.2.1-py3-none-any.whl
- Upload date:
- Size: 342.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbd499897ca976efbf289e6bb7c8026e0fbb97737185d04f84d0844f7ddb0575
|
|
| MD5 |
3e63b61be61a82374c6550be9cda089b
|
|
| BLAKE2b-256 |
1a31e9298318462f1132157ed579bb5b70e855cc322f0b0d67772281568cb215
|
Provenance
The following attestation bundles were made for stemtrace-0.2.1-py3-none-any.whl:
Publisher:
release.yml on iansokolskyi/stemtrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stemtrace-0.2.1-py3-none-any.whl -
Subject digest:
dbd499897ca976efbf289e6bb7c8026e0fbb97737185d04f84d0844f7ddb0575 - Sigstore transparency entry: 789746860
- Sigstore integration time:
-
Permalink:
iansokolskyi/stemtrace@75beb6928da0a0f102afc50cc4d412ea7ab7b8ac -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/iansokolskyi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@75beb6928da0a0f102afc50cc4d412ea7ab7b8ac -
Trigger Event:
push
-
Statement type: