Releases: astro-stack/django-orbit
v0.9.1 — Exception view & MCP server fixes
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_mcpcommand now setsDJANGO_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
[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 (soaccess_token,user_password,X-Api-Keyare all
caught) and recursive. Configurable viaMASK_KEYS. Newmask_sensitive_data()helper is
the single point used to scrub data before it is sent to an AI provider. Optional
MASK_ALL_PAYLOADSmasks 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 viaEXPLAIN_ANALYZE, only
ever run for read-onlySELECTs inside a rolled-back savepoint. Never runs during
recording. Configurable viaENABLE_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_CALLBACKsetting attaches tags automatically (e.g. by tenant, feature, status).
Filter by tag via?tag=fooor by typingtag:fooin 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 indexedfingerprintcolumn, so it
scales to large event volumes. Searching or drilling into a request still shows
individual occurrences. New migration backfillsfingerprintfor 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 navigation —
j/k(and arrows) move to the next/previous
entry in the current feed,Esccloses, 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_COLORSmaps, 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_JOBSinstead of the nonexistentRECORD_CELERY. - Updated pytest collection settings to ignore local transient directories such as
.pytest_cacheandorbit_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
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 behaviour — no 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_sizev0.8.0 — External Storage Backends
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 unaffected — DatabaseBackend 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
-
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, durationget_slow_queries— SQL queries above the slow-query threshold, sorted by durationget_exceptions— exceptions in a given time window with full tracebackget_n1_patterns— requests where N+1 duplicate queries were detectedsearch_entries— keyword search across all entry typesget_request_detail— every event (queries, logs, exceptions) for one request viafamily_hashget_stats_summary— error rate, avg response time, cache hit rate, top error paths
-
New optional dependency:
pip install django-orbit[mcp]installs themcp>=1.0package.
The core package remains dependency-free.
Configuration
ORBIT_CONFIG = {
'MCP_ENABLED': True, # default
}v0.6.4 - Connection Fix & Cachalot Compatibility
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:
migratefails on fresh database (#16) — Added_table_exists()guard torecord_command()andrecord_cache_operation()to prevent Orbit from writing toorbit_orbitentrybefore 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
ORBITsettings key support (backwards compatible withORBIT_CONFIG)
Upgrading
pip install django-orbit==0.6.4No migration changes required.
v0.6.3: Plug-and-Play module system & Health Dashboard
[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 watchersorbit.get_installed_watchers()- List of active watcher namesorbit.get_failed_watchers()- Dict of failed watchers with error messages
-
Configuration:
- Added
WATCHER_FAIL_SILENTLYsetting (default: True)- When True, module failures are logged but app continues
- When False, failures are re-raised for debugging
- Added
-
Dashboard Updates:
- New "Health" button in top navigation bar
- Fixed missing icons for Transaction and Storage types in feed
- Transactions now use
git-branchicon (teal color) - Storage now uses
archiveicon (sky color)
v0.6.2 - Fix Critical Crash with ATOMIC_REQUESTS
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
- Fixed OrbitAtomicWrapper compatibility with decorator usage (e.g.
v0.6.1 - Bug Fixes for Migrations & Command Watcher
[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,storagetypes
- Added migration 0004 with
- 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
[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
- Intercepts
- Storage Watcher: Monitor file storage operations
- Tracks
save,open,delete,existsoperations - Works with
FileSystemStorage(default) - Supports
S3Boto3Storage(django-storages) - Records file path, backend name, and operation duration
- Tracks
- 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_TRANSACTIONSsetting (default: True) - Added
RECORD_STORAGEsetting (default: True)
Technical
OrbitAtomicWrapperclass for safe atomic block interception- Storage patching via
create_patched_base()factory to avoid closure issues - Added
tests/test_transactions.pyandtests/test_storage.py