Observability (Prometheus, Grafana, Loki)
-
Metrics
/metricsendpoint + Postgres exporter. -
Dashboards
Grafana embedded with default UID
tribrid-overview. -
Logs
Loki + Promtail for container logs and app logs.
Sampling
Adjust tracing.trace_sampling_rate to manage cost and overhead. Use 1.0 in dev and 0.1–0.2 in production.
Anonymous Grafana
The compose stack enables anonymous access for embeds. Harden in production.
Timestamps
DOCKER_LOGS_TIMESTAMPS=1 helps correlate events across services.
Components
| Service | Port | Notes |
|---|---|---|
| Prometheus | 59090 | Scrapes /api/metrics and the Postgres exporter |
| Grafana | 3301 | Embedded dashboard in UI |
| Loki | 53100 | Log aggregation |
| Promtail | — | Ships container/host logs |
flowchart LR
App["ragweld API"] --> METRICS["/api/metrics"]
METRICS --> PROM["Prometheus"]
PROM --> GRAF["Grafana"]
LOGS["Docker Logs"] --> PROMTAIL["Promtail"]
PROMTAIL --> LOKI["Loki"]
LOKI --> GRAF "Latest" ML-quality gauges are read from persisted runs
The four "Latest" series behind the Eval / Benchmark / Prompt Regressions dashboard — tribrid_eval_last_top1_accuracy, tribrid_eval_last_topk_accuracy, tribrid_promptfoo_last_pass_ratio, and tribrid_benchmark_last_avg_latency_ms — are scraped from the most recently persisted eval / Promptfoo / benchmark run at scrape time, not set from whichever request happened to complete a run inside the current process. What that means operationally:
- Restarting the API cannot zero them. A freshly started process reports the persisted truth immediately; there is no window where the dashboard shows a green 0% beside runs that are on disk.
- No persisted run means no series at all. An absent series is the only honest encoding of "no data" Prometheus has, so the Grafana panels render "No data" instead of 0. A genuine 0% run is still exported as 0 — and the dashboard's thresholds render it red, never green.
- The benchmark directory follows config. The reader resolves
chat.benchmark.results_path, the same field the benchmark writer uses, so moving where benchmark runs land does not strand the latency gauge on a permanent "No data".
Probe hysteresis on the observability status
Component readiness behind /api/observability/status and the in-app Operator Deck debounces flapping probes: an incident needs tracing.probe_failure_threshold (default 3, env PROBE_FAILURE_THRESHOLD) consecutive failed probes, each component shows its last-8 probe history, and surfaces the API cannot probe at all (an auth-protected ingress that redirects off-host) never count as failures. See Tracing.
Dashboards
Mount your own Grafana provisioning under infra/grafana/provisioning to add/override dashboards and datasources.