Logs & Monitoring¶
Where logs come from¶
| Source | Format | Where |
|---|---|---|
| Hono API | JSON-ish lines via hono/logger |
stdout |
| WS server | Plain text | stdout |
| Next.js | Next's default | stdout |
| Docore agent / sandbox audit | Structured [audit], [docore] prefix |
stdout |
| PostgreSQL | Postgres log format | varies |
| Caddy / nginx | Access + error logs | /var/log/caddy/, /var/log/nginx/ |
| Cloudflare Tunnel | Plain text | journalctl |
Reading logs by deployment mode¶
Docker¶
docker compose -f docker/docker-compose.yml logs -f # all
docker compose -f docker/docker-compose.yml logs -f api ws web # filtered
docker compose -f docker/docker-compose.yml logs -f --tail 500 api
For long-term storage, run a logging driver:
β¦or ship to Loki / CloudWatch via the loki / awslogs drivers.
Bare-metal (systemd + tmux)¶
journalctl -u doable -f # the systemd unit (wraps tmux)
journalctl -u doable -e -n 1000 # last 1000 lines
journalctl -u cloudflared -f
sudo tail -f /var/log/caddy/access.log
sudo tail -f /var/log/caddy/error.log
If you want per-window logs (api / web / ws), tmux pipe-pane redirects each to a file:
tmux pipe-pane -t doable:api 'cat >>/var/log/doable/api.log'
tmux pipe-pane -t doable:web 'cat >>/var/log/doable/web.log'
tmux pipe-pane -t doable:ws 'cat >>/var/log/doable/ws.log'
Useful greps¶
# Auth failures
journalctl -u doable | grep -E '401|invalid_token'
# Sandbox denies
journalctl -u doable | grep '[audit] deny'
# AI provider errors
journalctl -u doable | grep -E 'anthropic|openai|copilot' | grep -i error
# Slow requests (> 1s)
journalctl -u doable | grep 'Server-Timing' | grep -E '\b[0-9]{4,}ms\b'
Health checks¶
Wire this up to your uptime monitor (UptimeRobot, BetterUptime, Pingdom) β alert on non-200 or missing db: ok.
Metrics¶
Doable doesn't ship a Prometheus endpoint by default. The Tracer from @doable/docore lets you hook OpenTelemetry exporters:
import { Tracer } from "@doable/docore";
const tracer = new Tracer({
sink: (span) => otelExporter.export(span),
});
Pass to DoCoreEngine. Spans cover session lifecycle, tool calls, and provider request timing.
For HTTP metrics, Hono's timing middleware emits Server-Timing headers β scrape from your edge proxy.
Suggested alert thresholds¶
| Signal | Threshold | Reason |
|---|---|---|
| 5xx rate | > 1% over 5 min | Real user impact |
| Auth-fail rate | > 10/sec | Brute-force or credential stuffing |
| Sandbox-deny rate | > 1/sec | Possibly compromised account |
| AI provider error rate | > 5% | Quota exhaustion or upstream outage |
Disk usage on PROJECTS_ROOT |
> 80% | Will affect new project creation |
| DB connections | > 80% of pool | Pool sized too small or query leak |
| WS connection drops | > 10/sec | Network issue or service crash |
Rotation¶
For bare-metal:
Drop in /etc/logrotate.d/doable.
For Docker, the json-file driver with max-size / max-file does the rotation in-place.