Monitoring Guide
Overview
SWIRL exposes health check and metrics endpoints for production monitoring. They integrate with standard tools such as Kubernetes, Prometheus, and alerting systems, so operators can track system health, detect issues, and maintain reliability.
For security-focused logging (authentication events, lockouts, SIEM forwarding), see the Security Guide.
Health Check Endpoints
SWIRL exposes health-check endpoints that report the status of critical system components, suitable for Kubernetes readiness and liveness probes.
/swirl/health/celery/ Endpoint
The /swirl/health/celery/ endpoint dispatches a ping task to the Celery workers and reports whether they respond. The same route is also available under the /api/swirl/ prefix.
Usage
To check the health of Celery workers:
curl http://localhost:8000/swirl/health/celery/
Example Response
A healthy response returns HTTP 200:
{
"status": "ok",
"message": "Celery is running and responsive"
}
An unresponsive or failing worker returns HTTP 500 with "status": "error" and a message describing the failure (for example, a ping timeout).
Kubernetes Configuration
Use this endpoint as a readiness probe to ensure traffic is only routed to healthy SWIRL instances:
apiVersion: v1
kind: Pod
metadata:
name: swirl-api
spec:
containers:
- name: swirl
image: swirlai/swirl-search-internal:<version>
livenessProbe:
httpGet:
path: /swirl/health/celery/
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /swirl/health/celery/
port: 8000
initialDelaySeconds: 10
periodSeconds: 5
Metrics Endpoints
SWIRL exposes Prometheus-compatible metrics endpoints for detailed monitoring and alerting integration.
/swirl/metrics/celery/ Endpoint
The /swirl/metrics/celery/ endpoint exposes Celery queue metrics in Prometheus format, including queue depth, active tasks, worker counts, and queue saturation.
Usage
To retrieve Celery metrics:
curl http://localhost:8000/swirl/metrics/celery/
Metrics Provided
The endpoint exposes metrics from the CeleryQueueCollector, including:
celery_queue_depth- Number of tasks waiting in each Celery queuecelery_queue_active_tasks- Number of currently executing tasks per queuecelery_queue_workers- Number of workers serving each queuecelery_queue_total_capacity- Total task capacity per queue (workers × concurrency)celery_queue_busy_ratio- Ratio of active tasks to total capacity per queuecelery_metrics_collection_error- Set to1if metrics collection fails
All gauges are labeled by queue. The queues are health_check, search, page_fetch, interactive, maintenance, and corpus; a totals label aggregates across the queues served by the instance.
Example Metrics Output
## HELP celery_queue_depth Number of tasks waiting in each Celery queue
## TYPE celery_queue_depth gauge
celery_queue_depth{queue="search"} 12
celery_queue_depth{queue="interactive"} 3
celery_queue_depth{queue="totals"} 15
## HELP celery_queue_active_tasks Number of currently executing tasks per queue on this pod
## TYPE celery_queue_active_tasks gauge
celery_queue_active_tasks{queue="search"} 2
celery_queue_active_tasks{queue="interactive"} 1
## HELP celery_queue_busy_ratio Ratio of active tasks to capacity on this pod per queue
## TYPE celery_queue_busy_ratio gauge
celery_queue_busy_ratio{queue="search"} 0.25
celery_queue_busy_ratio{queue="interactive"} 0.13
Prometheus Integration
Integrate SWIRL with Prometheus to collect and store metrics for analysis and alerting.
Configuration
Add the following scrape configuration to your prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'swirl'
static_configs:
- targets: ['localhost:8000']
metrics_path: '/swirl/metrics/celery/'
scrape_interval: 30s
scrape_timeout: 10s
Verifying Prometheus Integration
- Start Prometheus with the updated configuration:
prometheus --config.file=prometheus.yml
-
Open the Prometheus UI at
http://localhost:9090 -
Query SWIRL metrics:
celery_queue_depth
celery_queue_active_tasks
celery_queue_busy_ratio
Log Files
SWIRL maintains separate log files for different components, enabling granular troubleshooting and audit trails.
Log Locations
logs/django.log
Contains Django and API server activity: - HTTP request/response logs - Authentication and authorization events - API startup messages and initialization errors - Database connection issues
Example:
[2026-04-12 10:15:30] INFO [django.request] GET /swirl/search/ 200
[2026-04-12 10:15:45] WARNING [django.db] Slow query detected: 2.3s
[2026-04-12 10:16:00] ERROR [django.security] Failed login attempt from 192.168.1.100
logs/celery-*-worker.log
SWIRL runs one Celery worker per queue, each with its own log file:
logs/celery-search-worker.log- search federation executionlogs/celery-search-orchestrator-worker.log- search orchestrationlogs/celery-interactive-worker.log- chat, RAG, and other interactive taskslogs/celery-pagefetch-worker.log- Page Fetcher activitylogs/celery-maintenance-worker.log- cleanup and maintenance taskslogs/celery-healthcheck-worker.log- health-check pingslogs/celery-corpus-worker.log- ingestion and indexing
Worker logs contain result processing and aggregation, task processing errors, and worker startup and shutdown events.
Example:
[2026-04-12 10:15:32] INFO [celery.tasks] Task swirl.search.federate[id=abc123] started
[2026-04-12 10:15:45] WARNING [celery.search] Provider timeout: GoogleBooks (5.2s)
[2026-04-12 10:15:50] INFO [celery.tasks] Task swirl.search.federate[id=abc123] completed (5.8s)
logs/celery-beats.log
Contains scheduled task execution logs: - Subscription service runs - License expiration checks - Data cleanup and maintenance tasks - Search result expiration
Example:
[2026-04-12 00:05:00] INFO [celery.beat] Running scheduled task: cleanup_expired_results
[2026-04-12 12:00:00] INFO [celery.beat] Running scheduled task: check_subscriptions
[2026-04-12 06:00:00] WARNING [celery.beat] License expires in 7 days
Viewing Live Logs
Use the SWIRL CLI to tail all service logs in real-time:
python swirl.py logs
This command displays a live stream of logs from Django, Celery workers, and Celery Beat, making it easy to monitor system activity as it happens.
To view a specific log file:
tail -f logs/django.log
tail -f logs/celery-search-worker.log
tail -f logs/celery-beats.log
Key Metrics to Monitor
Monitor these critical metrics to ensure SWIRL operates reliably and efficiently.
Search Latency
What to monitor: Time from search creation (NEW_SEARCH) to completion (FULL_RESULTS_READY)
- Healthy: < 10 seconds for most searches
- Warning: 10-20 seconds (potential provider delays or network issues)
- Critical: > 20 seconds (investigate provider response times or queue congestion)
There is no per-task duration metric; measure end-to-end latency from the API or UI, and use queue saturation as the leading indicator:
celery_queue_busy_ratio{queue="search"}
celery_queue_depth{queue="search"}
Celery Queue Depth
What to monitor: Number of pending tasks in each queue
- Healthy: 0-10 tasks per queue
- Warning: 10-50 tasks (workers may be falling behind)
- Critical: > 50 tasks (worker shortage or performance degradation)
Query:
celery_queue_depth
Worker Memory Consumption
Monitor memory usage per worker to detect memory leaks and prevent out-of-memory crashes.
- Healthy: < 2 GB per worker
- Warning: 2-4 GB (check for memory leaks)
- Critical: > 4 GB (restart worker, investigate leaks)
Collection: Use system monitoring tools (Prometheus node_exporter) to scrape worker process metrics.
SearchProvider Response Times
Monitor response times and error rates for each data source:
- Healthy: < 5 seconds per provider
- Warning: 5-10 seconds
- Critical: > 10 seconds or error rate > 5%
How to track: Per-provider response times and errors are reported in the search worker log:
grep -i "timeout" logs/celery-search-worker.log
grep -i "error" logs/celery-search-worker.log
RAG Pipeline Duration
Monitor the time required to generate AI insights:
- Healthy: < 5 seconds
- Warning: 5-15 seconds
- Critical: > 15 seconds (check LLM provider availability)
RAG and chat tasks run on the interactive queue; monitor its saturation:
celery_queue_busy_ratio{queue="interactive"}
celery_queue_depth{queue="interactive"}
Rate Limiting
SWIRL implements API rate limiting to protect the system from overload and ensure fair resource allocation.
Configuration
SWIRL uses the DocsServiceUserIpThrottle throttle class for rate limiting based on user identity and IP address.
Chat Endpoint Rate Limiting
The default chat endpoint throttle rate is 15 requests per minute. It is configured with the DOCS_CHAT_THROTTLE_RATE environment variable in the .env file:
## .env
DOCS_CHAT_THROTTLE_RATE=15/minute
Adjust this setting to match your deployment requirements, then restart SWIRL:
## Increase to 30 requests per minute
DOCS_CHAT_THROTTLE_RATE=30/minute
Monitoring Rate Limit Hits
Monitor API throttling events in logs and metrics:
grep "Throttled" logs/django.log
If throttling is frequent, increase the throttle rate or add capacity.
Alerting Recommendations
Configure alerts to proactively notify operations teams of potential issues.
Recommended Alert Thresholds
Disk Usage
alert:
- name: HighDiskUsage
condition: disk_usage_percent > 80
severity: warning
action: Review logs and clean up old results
- name: CriticalDiskUsage
condition: disk_usage_percent > 95
severity: critical
action: Immediately clean up results or expand storage
Celery Queue Depth
alert:
- name: HighQueueDepth
condition: celery_queue_depth > 50
severity: warning
action: Scale up worker count or investigate performance
- name: QueueBacklog
condition: celery_queue_depth > 200
severity: critical
action: Immediately scale workers or pause new searches
Worker Health
alert:
- name: WorkerOffline
condition: celery_queue_workers == 0 for any queue
severity: critical
action: Restart worker, check logs for errors
- name: HighWorkerMemory
condition: worker_memory_mb > 4096
severity: warning
action: Investigate memory leak, restart worker if persistent
License Expiration
alert:
- name: LicenseExpiringSoon
condition: days_until_expiration < 30
severity: warning
action: Renew license before expiration
- name: LicenseExpired
condition: current_date > license_expiration_date
severity: critical
action: Renew license immediately to restore functionality
Provider Availability
alert:
- name: ProviderHighErrorRate
condition: provider_error_rate > 5%
severity: warning
action: Check provider status page, verify credentials
- name: ProviderTimeout
condition: provider_response_time > 10 seconds
severity: warning
action: Check network connectivity, adjust timeout settings
Search Latency
alert:
- name: SearchLatencyHigh
condition: search_duration_p95 > 20 seconds
severity: warning
action: Review provider performance, check queue depth
Setting Up Alerts in Prometheus
Add alerting rules to prometheus-rules.yml:
groups:
- name: swirl_alerts
interval: 30s
rules:
- alert: HighCeleryQueueDepth
expr: celery_queue_depth > 50
for: 5m
labels:
severity: warning
annotations:
summary: "High Celery queue depth detected"
description: "Queue {{ $labels.queue }} has {{ $value }} pending tasks"
- alert: WorkerMemoryHigh
expr: process_resident_memory_bytes > 4294967296
for: 10m
labels:
severity: warning
annotations:
summary: "Worker memory usage exceeding 4GB"
description: "Worker {{ $labels.worker }} is using {{ $value }} bytes"
The WorkerMemoryHigh rule uses process_resident_memory_bytes, which requires a process or node exporter alongside SWIRL; it is not exposed by the SWIRL metrics endpoint.
Configure notifications via Alertmanager to email, Slack, or PagerDuty:
## alertmanager.yml
route:
receiver: 'default'
group_wait: 30s
group_interval: 5m
repeat_interval: 12h
receivers:
- name: 'default'
slack_configs:
- api_url: 'YOUR_SLACK_WEBHOOK_URL'
channel: '#alerts'
title: 'SWIRL Alert'
Need Help?
For additional support and questions about monitoring SWIRL: - Review the User Guide for system operation - Check the Architecture documentation for system design - Visit the SWIRL GitHub Issues for known issues