Monitoring
How to monitor the health and performance of the ION Guard platform in production.
Health Check
HTTP endpoint
GET /api/v1/health
Requires no authentication. Returns the state of all components:
{
"status": "healthy",
"components": {
"database": {
"status": "ok",
"latency_ms": 5.23
},
"redis": {
"status": "ok",
"latency_ms": 2.14
},
"queue": {
"status": "ok",
"size": 42
}
}
}
Possible statuses
| Status | HTTP | Meaning |
|---|---|---|
| healthy | 200 | All components OK |
| degraded | 200 | Non-critical components with issues (e.g., queue > 1000 items) |
| unhealthy | 503 | Critical components failing (database or redis) |
Monitored components
| Component | Check | Critical |
|---|---|---|
| Database | SELECT 1 + latency | Yes |
| Redis | PING + latency | Yes |
| Queue | Size of the queues:default queue | No (> 1000 = error) |
Health check script
For a complete check including Docker containers:
cd /home/iongrade/ionguard
./scripts/healthcheck.sh
This script checks:
- HTTP endpoint —
GET /api/v1/healthreturns 200 - Horizon —
php artisan horizon:statusconfirms active workers - Containers — Each core and module container is
runningandhealthy
Returns exit code 0 (success) or 1 (failure).
External monitoring
Use the /api/v1/health endpoint with monitoring tools:
# Example with cron (every 5 minutes)
*/5 * * * * curl -sf https://ionguard.local/api/v1/health -k || \
echo "ION Guard unhealthy" | mail -s "Alerta" admin@empresa.com
# Example with UptimeRobot, Pingdom, etc.
# URL: https://ionguard.local/api/v1/health
# Expect: HTTP 200
# Keyword: "healthy"
Container Health Checks
Each container has its own health check verified by Docker:
| Container | Check | Interval | Retries |
|---|---|---|---|
| MariaDB | healthcheck.sh --connect --innodb_initialized | 10s | 3 |
| Valkey | valkey-cli ping | 10s | 3 |
| InfluxDB | influx ping | 30s | 3 |
| Mosquitto | TCP connect on port 1883 | 30s | 3 |
| Horizon | php artisan horizon:status | 60s | 1 |
Containers with dependencies wait for their prerequisites to become healthy before starting:
- PHP waits for MariaDB and Valkey
- Horizon and Scheduler wait for MariaDB and Valkey
- Mosquitto waits for MariaDB
Logs
Application logs
# PHP logs (errors, warnings)
./scripts/comp.sh logs -f ionguard_php --tail 100
# Or directly in the file
./scripts/comp.sh exec -T ionguard_php tail -100 storage/logs/laravel.log
Logs by service
# Queue workers (Horizon)
./scripts/comp.sh logs -f ionguard_horizon --tail 100
# Scheduler
./scripts/comp.sh logs -f ionguard_scheduler --tail 50
# WebSocket (Reverb)
./scripts/comp.sh logs -f ionguard_reverb --tail 50
# MQTT Broker
./scripts/comp.sh logs -f ionguard_mosquitto --tail 50
# Nginx (access + error)
./scripts/comp.sh logs -f ionguard_nginx --tail 50
Module log
Installation and uninstallation operations are recorded separately:
./scripts/comp.sh exec -T ionguard_php tail -50 storage/logs/modules.log
Configurable log channels
| Channel | File | Rotation | Default level | Days variable |
|---|---|---|---|---|
| daily | storage/logs/laravel.log | Daily (14 days) | LOG_LEVEL (default debug) | LOG_DAILY_DAYS |
| modules | storage/logs/modules.log | Daily (14 days) | info (fixed, independent of the global LOG_LEVEL) | LOG_MODULES_DAYS |
| structured | storage/logs/structured.log | Daily (14 days) | LOG_LEVEL (default debug) | LOG_DAILY_DAYS |
The modules channel is intentionally independent of the global LOG_LEVEL — it guarantees info-level traces of install/uninstall operations even when the rest of the application is at warning. The level can be adjusted via LOG_MODULES_LEVEL.
Configurable via .env: LOG_CHANNEL (default stack), LOG_STACK (default single), LOG_LEVEL (default debug), LOG_DAILY_DAYS, LOG_MODULES_DAYS, LOG_MODULES_LEVEL.
Retention metrics
Time-series data (BLE signals in InfluxDB) and other data follow retention policies configurable via .env:
| Data | Default | .env variable |
|---|---|---|
| BLE signals | 7 days | RETENTION_SIGNALS_DAYS |
| Location history | 90 days | RETENTION_LOCATIONS_DAYS |
| Events | 365 days | RETENTION_EVENTS_DAYS |
| Audit records | 365 days | RETENTION_AUDIT_DAYS |
Cleanup of signal/location history is run by the AggregateLocationHistoryJob, provided by the Synapsys (Indoor Location) module — therefore available only on installations with that module active.
Useful commands
# Full status
./scripts/comp.sh ps
# Installed version
./scripts/getVersion.sh
# Disk space of the volumes
docker system df
# Container memory usage
docker stats --no-stream