Skip to main content

A lightweight Celery task flow visualizer

Project description

stemtrace ๐ŸŒฟ

Zero-infrastructure Celery task flow visualizer

PyPI version Python CI codecov License: MIT Code style: ruff Type checked: mypy


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() and chord() 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.

Task detail view showing parameters, result, and timeline

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.

Chord visualization in the workflow graph

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).

Task registry showing not-registered warning and status badges

๐Ÿš€ 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stemtrace-0.2.0.tar.gz (863.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stemtrace-0.2.0-py3-none-any.whl (340.7 kB view details)

Uploaded Python 3

File details

Details for the file stemtrace-0.2.0.tar.gz.

File metadata

  • Download URL: stemtrace-0.2.0.tar.gz
  • Upload date:
  • Size: 863.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for stemtrace-0.2.0.tar.gz
Algorithm Hash digest
SHA256 debba1de0e606df2ce0da8e8ba22a75fd3620b706337810164d8205e96112e09
MD5 c81f829af0e9fa17a1049d68b143a792
BLAKE2b-256 105acaef0eedc67ea631162f3cf3b9ae6739251f6b6999e274d5a74ff43e8ce2

See more details on using hashes here.

Provenance

The following attestation bundles were made for stemtrace-0.2.0.tar.gz:

Publisher: release.yml on iansokolskyi/stemtrace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stemtrace-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: stemtrace-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 340.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for stemtrace-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 102fae9b2744d6859317f3ce9e7155fca333a528850fccd5a8f43253e30037b9
MD5 b5a93c2702582dc5b874c3da0b953135
BLAKE2b-256 1217c25d60e7969bcc632214d66989151f93cc35ef8a4ccbbf556ae672d5a19f

See more details on using hashes here.

Provenance

The following attestation bundles were made for stemtrace-0.2.0-py3-none-any.whl:

Publisher: release.yml on iansokolskyi/stemtrace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page