--- name: loki description: Log aggregation with Loki and Promtail metadata: version: "1.0.0" vibestack: main: false metrics-port: 3100 --- # Loki Skill Log aggregation using [Grafana Loki](https://grafana.com/oss/loki/) with Promtail for log shipping. ## Features - Lightweight log storage (indexes labels, not content) - Auto-discovers skill logs from supervisor - Prometheus-compatible metrics - LogQL query language - Auto-registers with Caddy if present ## Architecture ``` supervisor logs ──► promtail ──► loki ──► /loki/api/v1/query /var/log/supervisor/*.log :3100 ``` ## Configuration | Variable | Description | Default | |----------|-------------|---------| | `LOKI_PORT` | Loki API port | `3100` | | `LOKI_DATA_DIR` | Data storage directory | `/data/loki` | | `LOKI_RETENTION` | Log retention period | `168h` (7 days) | | `LOKI_DOMAIN` | Domain for Caddy auto-config | (none) | | `SUPERVISOR_LOG_DIR` | Where to find skill logs | `/var/log/supervisor` | ## Querying Logs ### Via API ```bash # All logs from last hour curl -G "http://localhost:3100/loki/api/v1/query_range" \ --data-urlencode 'query={job="skills"}' \ --data-urlencode 'start=1h' # Logs from specific skill curl -G "http://localhost:3100/loki/api/v1/query_range" \ --data-urlencode 'query={skill="caddy"}' # Search for errors curl -G "http://localhost:3100/loki/api/v1/query_range" \ --data-urlencode 'query={job="skills"} |= "error"' ``` ### LogQL Examples ```logql # All skill logs {job="skills"} # Specific skill {skill="ttyd"} # Filter by content {job="skills"} |= "error" {job="skills"} |~ "error|warn" # JSON parsing (if logs are JSON) {job="skills"} | json | level="error" ``` ## Integration with Grafana Add Loki as a data source: - URL: `http://loki:3100` (or via Caddy proxy) - Access: Server ## Metrics Loki exposes Prometheus metrics at `:3100/metrics`: - `loki_ingester_streams_created_total` - `loki_distributor_bytes_received_total` - `loki_querier_query_duration_seconds`