Satellite Observability for Django
A debugging and observability dashboard that orbits your app without touching it.
๐ Documentation ยท ๐ฎ Try the Demo ยท โญ Star on GitHub
- Why Orbit?
- What Orbit tracks
- Installation
- Quick Start
- Try the Demo
- Configuration
- Dashboards
- MCP Server โ AI Assistant Integration
- Background Job Integrations
- Health & Plug-and-Play
- Storage Backends
- Security
- Roadmap
- Contributing
Unlike Django Debug Toolbar โ which injects HTML into your templates โ Django Orbit lives at its own isolated URL (/orbit/). It observes your application from a distance, like a satellite, without interfering with it.
| Django Debug Toolbar | Django Orbit | |
|---|---|---|
| Template injection | โ Yes | โ No |
| Works with APIs / SPAs | โ No | โ Yes |
| SQL + logs + exceptions | Partial | โ All in one |
| Background jobs | โ | โ Celery, RQ, Django-Q |
| AI assistant integration | โ | โ MCP Server |
| Health / module status | โ | โ |
Inspired by Laravel Telescope.
| Category | Events |
|---|---|
| HTTP | Requests, responses, headers, body, status codes |
| Database | SQL queries, slow queries, N+1 detection |
| Logging | All Python logging output, any level |
| Exceptions | Full traceback, request context |
| Cache | GET hits/misses, SET, DELETE (any backend) |
| Models | ORM create, update, delete events |
| Commands | manage.py executions with exit code |
| HTTP Client | Outgoing requests via requests / httpx |
| Sent emails with headers and body | |
| Signals | Django signal dispatches |
| Background Jobs | Celery, Django-Q, RQ, APScheduler |
| Redis | GET, SET, DEL, HGET, LPUSH, and more |
| Permissions | Authorization checks, granted/denied |
| Transactions | atomic() blocks, commits, rollbacks |
| Storage | File save/open/delete (local + S3) |
All events are linked by family_hash, so you can see every query, log, and exception that occurred within a single request.
pip install django-orbit
# With MCP support (AI assistant integration โ Claude, Cursor, Copilot)
pip install django-orbit[mcp]1. Add to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
'orbit',
]2. Add middleware (early in the list):
MIDDLEWARE = [
'orbit.middleware.OrbitMiddleware',
# ...
]3. Include URLs:
from django.urls import path, include
urlpatterns = [
path('orbit/', include('orbit.urls')),
# ...
]4. Migrate and run:
python manage.py migrate orbit
python manage.py runservergit clone https://github.com/astro-stack/django-orbit.git
cd django-orbit
pip install -e .
python demo.py setup
python manage.py runserver| URL | |
|---|---|
http://localhost:8000/ |
Demo app |
http://localhost:8000/orbit/ |
Orbit Dashboard |
http://localhost:8000/orbit/stats/ |
Stats Dashboard |
http://localhost:8000/orbit/health/ |
Health Dashboard |
All settings go in ORBIT_CONFIG (or ORBIT) in your settings.py. Everything has a sensible default โ you only need to set what you want to change.
ORBIT_CONFIG = {
'ENABLED': True, # set to DEBUG to auto-disable in production
'SLOW_QUERY_THRESHOLD_MS': 500,
'STORAGE_LIMIT': 1000, # max entries to keep
# Watchers โ all enabled by default
'RECORD_REQUESTS': True,
'RECORD_QUERIES': True,
'RECORD_LOGS': True,
'RECORD_EXCEPTIONS': True,
'RECORD_COMMANDS': True,
'RECORD_CACHE': True,
'RECORD_MODELS': True,
'RECORD_HTTP_CLIENT': True,
'RECORD_MAIL': True,
'RECORD_SIGNALS': True,
'RECORD_JOBS': True,
'RECORD_REDIS': True,
'RECORD_GATES': True,
'RECORD_TRANSACTIONS': True,
'RECORD_STORAGE': True,
# Security
'AUTH_CHECK': lambda request: request.user.is_staff,
'IGNORE_PATHS': ['/orbit/', '/static/', '/media/'],
# Resilience
'WATCHER_FAIL_SILENTLY': True, # failed watchers log errors but don't crash the app
}HTMX-powered live feed with 3-second polling. Filter by event type, search by keyword, export to JSON, and click any entry to see its full detail in a slide-over panel.
| Metric | |
|---|---|
| Apdex Score | User satisfaction index (0โ1) |
| Percentiles | P50, P75, P95, P99 response times |
| Error Rate | Failure percentage with trend |
| Throughput | Requests per minute / hour |
| Slow Queries | Count and top offenders |
| Cache Hit Rate | Sparkline chart |
| Job Success Rate | Per-backend breakdown |
| Top Denied Permissions | Authorization audit |
Time range filters: 1h ยท 6h ยท 24h ยท 7d
Shows the status of every Orbit module:
- ๐ข Healthy โ working normally
- ๐ด Failed โ initialization error (click for full traceback)
- ๐ก Disabled โ turned off via config
Django Orbit exposes your telemetry as an MCP (Model Context Protocol) server. Connect Claude, Cursor, Windsurf, or any MCP-compatible AI assistant and ask questions directly against your app's live data.
Examples:
- "Why is
/api/orders/slow?" - "What exceptions occurred in the last hour?"
- "Find all N+1 patterns in the app"
- "Show me everything that happened during this request"
pip install django-orbit[mcp]// Claude Desktop โ claude_desktop_config.json
// Cursor โ .cursor/mcp.json
// Windsurf โ .windsurfrc
{
"mcpServers": {
"django-orbit": {
"command": "python",
"args": ["manage.py", "orbit_mcp"],
"cwd": "/path/to/your/django/project"
}
}
}The MCP server launches on-demand when your AI assistant needs it. No extra process to manage.
| Tool | What it returns |
|---|---|
get_recent_requests |
Last N requests with status, path, duration |
get_slow_queries |
SQL queries above threshold, sorted by duration |
get_exceptions |
Exceptions in a time window with full traceback |
get_n1_patterns |
Requests where N+1 duplicate queries were detected |
get_request_detail |
Every event for one request via family_hash |
search_entries |
Keyword search across all event types |
get_stats_summary |
Error rate, avg response time, cache hit rate |
| Backend | How |
|---|---|
| Celery | Via signals (automatic) |
| Django-Q | Via signals (automatic) |
| RQ | Worker monkey-patching (automatic) |
| APScheduler | register_apscheduler(scheduler) |
| django-celery-beat | Via model signals (automatic) |
Each watcher initializes independently. If Celery isn't installed, only the Celery watcher fails โ everything else keeps working.
from orbit import get_watcher_status, get_failed_watchers
get_watcher_status()
# {'cache': {'installed': True, 'error': None, 'disabled': False}, ...}
get_failed_watchers()
# {'celery': 'ModuleNotFoundError: No module named celery'}By default Orbit stores events in your project's default database. For production you can route all Orbit writes to a dedicated database so telemetry doesn't compete with application traffic.
# 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| Backend | Description |
|---|---|
orbit.backends.database.DatabaseBackend |
Default โ uses default DB, no config needed |
orbit.backends.django_db.DjangoDBBackend |
Dedicated Django database alias |
Restrict access using any callable:
ORBIT_CONFIG = {
# Staff only
'AUTH_CHECK': lambda request: request.user.is_staff,
# Disable entirely in production
'ENABLED': DEBUG,
}Orbit automatically redacts sensitive fields (passwords, tokens, API keys) from request bodies and headers.
- AI Insights engine โ automatic pattern detection and plain-English summaries powered by LLMs
- VS Code / Cursor extension โ surface Orbit data in your editor sidebar while you code
- Alerting โ Slack, email, and webhook notifications for exceptions and slow requests
- Orbit Cloud โ shared team dashboards with historical data retention
Contributions are welcome! See CONTRIBUTING.md for guidelines.
MIT โ see LICENSE.
Inspired by Laravel Telescope, Spatie Ray, and Django Debug Toolbar.