Skip to content

Releases: astro-stack/django-orbit

v0.9.1 — Exception view & MCP server fixes

15 Jun 15:27
26cb195

Choose a tag to compare

Patch release with two fixes.

Fixed

  • MCP server runtime crash — every tool call failed with "You cannot call this from an async context" because the tools use the synchronous Django ORM inside FastMCP's async loop. The orbit_mcp command now sets DJANGO_ALLOW_ASYNC_UNSAFE (safe for this local, single-user stdio server), so AI assistants can actually query Orbit.
  • Hidden exceptions — exceptions without a fingerprint were no longer shown in the grouped Exceptions view (the sidebar badge could show a count while the list said "No exceptions"). They now appear individually; fingerprinted exceptions still group together. Grouping uses COALESCE(NULLIF(fingerprint, ''), id), portable across SQLite / MySQL / PostgreSQL.

Install: pip install -U django-orbit

Full changelog: https://github.com/astro-stack/django-orbit/blob/main/CHANGELOG.md

v0.9.0 - UX changes, Security fixes and improvements

15 Jun 14:01

Choose a tag to compare

[0.9.0] - 2026-06-15

Security

  • Sensitive-data masking — values whose key contains a sensitive term (password,
    token, api_key, authorization, secret, cookie, …) are redacted. Matching is now
    substring + case-insensitive (so access_token, user_password, X-Api-Key are all
    caught) and recursive. Configurable via MASK_KEYS. New mask_sensitive_data() helper is
    the single point used to scrub data before it is sent to an AI provider. Optional
    MASK_ALL_PAYLOADS masks every entry payload at write time (off by default).

Added

  • Query EXPLAIN — run a query plan on demand from a query's detail panel
    (Explain plan). Vendor-aware (PostgreSQL / MySQL / SQLite) with graceful fallback.
    EXPLAIN ANALYZE (which executes the statement) is opt-in via EXPLAIN_ANALYZE, only
    ever run for read-only SELECTs inside a rolled-back savepoint. Never runs during
    recording. Configurable via ENABLE_EXPLAIN.
  • Request waterfall — a request's child queries are shown as a timeline of bars
    positioned by each query's real start offset within the request (captured at execution),
    sized by duration, colored for slow/duplicate. Click a bar to open that query.
  • Tagging + tag search — entries can carry tags (indexed, comma-wrapped). A
    TAG_CALLBACK setting attaches tags automatically (e.g. by tenant, feature, status).
    Filter by tag via ?tag=foo or by typing tag:foo in the search box; tags show as
    clickable chips in the detail panel.
  • Exception grouping — identical exceptions (same type + raise location) are collapsed
    into a single row on the Exceptions view, with an occurrence count and first/last seen.
    Grouping/counting is done in the database via a new indexed fingerprint column, so it
    scales to large event volumes. Searching or drilling into a request still shows
    individual occurrences. New migration backfills fingerprint for existing exceptions.
  • Grouped, collapsible sidebar navigation — entry types are organized into
    Core / Infrastructure / Application groups for progressive disclosure, instead of a
    flat 16-item list. The group containing the active type opens automatically.
  • Standalone "All Events" item above the type groups (it is a meta-filter, not an
    entry type).
  • Compact KPI strip on the dashboard (requests, queries, avg, errors, slow, N+1)
    replacing the bulky four-card panel, leaving more room for the feed.
  • Detail panel keyboard navigationj/k (and arrows) move to the next/previous
    entry in the current feed, Esc closes, with on-panel prev/next buttons and a position
    indicator.
  • First-run onboarding tour — a dismissable welcome overlay explaining the layout and
    shortcuts, reopenable from the ? button in the top bar.
  • Lazy-loaded Stats sections — trends, database, cache, jobs and security each load
    via their own /orbit/stats/section/<name>/ endpoint.
  • DESIGN.md — a project design system documenting tokens, components and principles.

Changed

  • Visual overhaul toward a calmer, Linear-inspired minimal UI: softened glow/gradient
    decoration, consistent badges and cards, reduced-motion support.
  • Stats page paints fast — only the headline (Apdex, avg/P95, error rate, throughput,
    percentiles) is computed up front; heavier sections load lazily. This removes the
    SQLite "database is locked" retry workaround.
  • Sidebar and feed are now driven from a single nav config and the model's TYPE_ICONS/
    TYPE_COLORS maps, eliminating duplicated per-type markup.

Fixed

  • The "Entry Details" slide-over no longer flashes open on page load (added x-cloak),
    most visible when opening the Stats page.
  • The dashboard and Health pages no longer display a hardcoded stale version; both now
    read the installed package version.
  • The feed no longer jumps to the top on background polling — scroll position is preserved.
  • Hardened filesystem-related tests on Windows so the suite no longer depends on writable temp/cache directories with unstable permissions.
  • Fixed the Health dashboard guidance to use RECORD_JOBS instead of the nonexistent RECORD_CELERY.
  • Updated pytest collection settings to ignore local transient directories such as .pytest_cache and orbit_test_storage.

Removed

  • The "Export Filtered" button in the sidebar. Per-entry JSON export remains available
    from the detail panel.

Documentation

  • Replaced placeholder Quick Start, API, and Customization pages with current project documentation.
  • Corrected the docs metadata URL to point to the published MkDocs site.
  • Updated troubleshooting and contributing docs to match the current configuration and docs workflow.

v0.8.1 — HTML Email Preview + MySQL bulk_create fix

09 Apr 00:36

Choose a tag to compare

What's New

HTML Email Preview (#14)

Emails sent via EmailMultiAlternatives now show a Plain text / HTML preview tab switcher in the dashboard detail
panel. The HTML body renders in a sandboxed <iframe> — no external scripts, safe to use in any environment.

  • Plain-text-only emails (EmailMessage) are unaffected
  • HTML body capped at 100 KB during capture

BULK_CREATE_BATCH_SIZE config key (#19)

Fixes OperationalError: (2006, 'Server has gone away') on MySQL when a single request triggers a very large number
of SQL queries, exceeding max_allowed_packet.

ORBIT_CONFIG = {
    "BULK_CREATE_BATCH_SIZE": 500,  # None = original behaviour (default)
}

Setting this splits the internal bulk_create into batches. None keeps the original single-INSERT behaviourno change
 needed if you're not on MySQL or not hitting this error.

Install

pip install django-orbit==0.8.1

Docs

- HTML email preview: https://astro-stack.github.io/django-orbit/dashboard/#mail-html-preview
- BULK_CREATE_BATCH_SIZE: https://astro-stack.github.io/django-orbit/configuration/#bulk_create_batch_size

v0.8.0 — External Storage Backends

09 Apr 00:35

Choose a tag to compare

What's New

External Storage Backends

Route all Orbit writes to a dedicated Django database alias instead of your app's default database.

Two backends included:

Backend Description
orbit.backends.database.DatabaseBackend Default — uses default DB, zero config change
orbit.backends.django_db.DjangoDBBackend Dedicated Django database alias

Usage:

# settings.py
DATABASES = {
    "default": { ... },
    "orbit": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "orbit.sqlite3",
    },
}

ORBIT_CONFIG = {
    "STORAGE_BACKEND": "orbit.backends.django_db.DjangoDBBackend",
    "STORAGE_DB_ALIAS": "orbit",
}

python manage.py migrate orbit --database=orbit

All existing users are unaffectedDatabaseBackend is the default and behaves identically to previous versions.

Install

pip install django-orbit==0.8.0

Docs

https://astro-stack.github.io/django-orbit/storage-backends/

**Assets:** `django_orbit-0.8.0-py3-none-any.whl`, `django_orbit-0.8.0.tar.gz`

v0.7.0: MCP Server to expose Orbit telemetry

03 Apr 05:37

Choose a tag to compare

  • MCP Server (python manage.py orbit_mcp): Expose Orbit telemetry as an
    MCP (Model Context Protocol) server so AI
    assistants like Claude, Cursor, and Copilot can query your app's observability
    data directly.

    Tools available to the AI:

    • get_recent_requests — last N HTTP requests with status, path, duration
    • get_slow_queries — SQL queries above the slow-query threshold, sorted by duration
    • get_exceptions — exceptions in a given time window with full traceback
    • get_n1_patterns — requests where N+1 duplicate queries were detected
    • search_entries — keyword search across all entry types
    • get_request_detail — every event (queries, logs, exceptions) for one request via family_hash
    • get_stats_summary — error rate, avg response time, cache hit rate, top error paths
  • New optional dependency: pip install django-orbit[mcp] installs the mcp>=1.0 package.
    The core package remains dependency-free.

Configuration

ORBIT_CONFIG = {
    'MCP_ENABLED': True,  # default
}

v0.6.4 - Connection Fix & Cachalot Compatibility

30 Mar 23:14

Choose a tag to compare

What's New

Fixed

  • Critical: DB connections exhausted (#15) — _table_exists() now caches its result at process level. Previously it ran a full schema introspection query on every cache hit, model save, or management command event, spiking DB connections under load.
  • Critical: migrate fails on fresh database (#16) — Added _table_exists() guard to record_command() and record_cache_operation() to prevent Orbit from writing to orbit_orbitentry before migrations have created it (fixes PostgreSQL transaction poisoning).
  • Critical: RecursionError with django-cachalot (#10) — Wrapped all internal Orbit writes in cachalot_disabled() to break the infinite invalidation loop.
  • Crash on anonymous signals (#7) — Safe sender name resolution prevents AttributeError.

Added

  • Duplicate Query Detection (N+1) with "DUP" badge and filter
  • Top Slowest Queries highlighted in entry detail view
  • ORBIT settings key support (backwards compatible with ORBIT_CONFIG)

Upgrading

pip install django-orbit==0.6.4

No migration changes required.

v0.6.3: Plug-and-Play module system & Health Dashboard

25 Jan 21:14

Choose a tag to compare

[0.6.3] - 2026-01-25

Added

  • Plug-and-Play Module System: Each watcher/module now operates independently

    • If one module fails to initialize, others continue working normally
    • Failed modules are logged but don't crash the application
    • Module status is tracked and available for diagnostics
  • Health Dashboard (/orbit/health/): New diagnostics page showing module status

    • Visual indicators: Green (healthy), Red (failed), Yellow (disabled)
    • Expandable error details with full traceback
    • Summary cards for total/healthy/failed/disabled counts
    • Instructions for fixing failed modules
  • New API Functions:

    • orbit.get_watcher_status() - Get status of all watchers
    • orbit.get_installed_watchers() - List of active watcher names
    • orbit.get_failed_watchers() - Dict of failed watchers with error messages
  • Configuration:

    • Added WATCHER_FAIL_SILENTLY setting (default: True)
      • When True, module failures are logged but app continues
      • When False, failures are re-raised for debugging
  • Dashboard Updates:

    • New "Health" button in top navigation bar
    • Fixed missing icons for Transaction and Storage types in feed
    • Transactions now use git-branch icon (teal color)
    • Storage now uses archive icon (sky color)

v0.6.2 - Fix Critical Crash with ATOMIC_REQUESTS

23 Jan 15:03

Choose a tag to compare

Fixed

  • Critical crash with ATOMIC_REQUESTS=True (Issue #5)
    • Fixed OrbitAtomicWrapper compatibility with decorator usage (e.g. @transaction.atomic).
    • Added thread safety for nested atomic blocks and concurrent requests.
      Full Changelog: v0.6.1...v0.6.2

v0.6.1 - Bug Fixes for Migrations & Command Watcher

22 Jan 23:16

Choose a tag to compare

[0.6.1] - 2026-01-22

Fixed

  • Missing migration for entry types added in v0.4.0-v0.6.0 (Issue #3)
    • Added migration 0004 with mail, signal, redis, gate, transaction, storage types
  • Command watcher breaking interactive commands like collectstatic (Issue #4)
    • Removed stdout/stderr redirection that prevented user input
    • Commands now execute normally while still being recorded

v0.6.0 - Transaction & Storage Monitoring

22 Jan 23:03

Choose a tag to compare

[0.6.0] - 2025-01-22

Added

  • Transaction Watcher: Track database transaction blocks
    • Intercepts transaction.atomic() context managers
    • Records commit/rollback status
    • Captures transaction duration in milliseconds
    • Logs exceptions that trigger rollbacks
  • Storage Watcher: Monitor file storage operations
    • Tracks save, open, delete, exists operations
    • Works with FileSystemStorage (default)
    • Supports S3Boto3Storage (django-storages)
    • Records file path, backend name, and operation duration
  • Dashboard Updates:
    • New "Transactions" filter with teal icon (layers)
    • New "Storage" filter with sky-blue icon (archive)
    • Summary formatting for transaction status (✓/✗ icons)

Configuration

  • Added RECORD_TRANSACTIONS setting (default: True)
  • Added RECORD_STORAGE setting (default: True)

Technical

  • OrbitAtomicWrapper class for safe atomic block interception
  • Storage patching via create_patched_base() factory to avoid closure issues
  • Added tests/test_transactions.py and tests/test_storage.py