Legger til observerbarhetslaget i maskinrommet: - Strukturert JSON-logging via LOG_FORMAT=json (maskinlesbart for log-aggregering). Default er human-readable for utvikling. - Ny metrics-modul med in-memory request latency tracking per rute (count, avg, min, max, p50/p95/p99 fra siste 1000 forespørsler). - Custom axum-middleware erstatter tower_http::TraceLayer — logger method, path, status og duration_ms per request, og mater metrikk-samleren. - GET /metrics-endepunkt som returnerer: - request_latency: per-rute statistikk - queue_depth: pending/running/error/retry fra job_queue - ai_cost: aggregert fra ai_usage_log (siste time/24h/30d) - Default loggnivå endret fra debug til info for mindre støy.
104 lines
2.2 KiB
Markdown
104 lines
2.2 KiB
Markdown
# Observerbarhet
|
|
|
|
Maskinrommets observerbarhetslag: strukturert logging, request-metrikker,
|
|
jobbkø-dybde og AI-kostnadsovervåking.
|
|
|
|
## Strukturert logging
|
|
|
|
Maskinrommet bruker `tracing` med `tracing-subscriber`. Format velges via
|
|
miljøvariabel:
|
|
|
|
| `LOG_FORMAT` | Resultat |
|
|
|---|---|
|
|
| `json` | JSON-linjer (maskinlesbart, egnet for log-aggregering) |
|
|
| *(annet/utelatt)* | Human-readable (standard for utvikling) |
|
|
|
|
Loggnivå styres via `RUST_LOG` (default: `maskinrommet=info`).
|
|
|
|
### JSON-format eksempel
|
|
|
|
```json
|
|
{"timestamp":"2026-03-18T12:00:00Z","level":"INFO","fields":{"method":"GET","path":"/health","status":200,"duration_ms":1.2},"target":"maskinrommet::metrics","message":"request"}
|
|
```
|
|
|
|
## Metrikk-endepunkt
|
|
|
|
`GET /metrics` returnerer JSON med tre seksjoner:
|
|
|
|
### request_latency
|
|
|
|
In-memory per-rute statistikk (nullstilles ved restart):
|
|
|
|
```json
|
|
{
|
|
"uptime_secs": 3600,
|
|
"total_requests": 1234,
|
|
"routes": {
|
|
"/health": {
|
|
"count": 500,
|
|
"avg_ms": 1.2,
|
|
"min_ms": 0.3,
|
|
"max_ms": 15.0,
|
|
"p50_ms": 0.8,
|
|
"p95_ms": 3.5,
|
|
"p99_ms": 12.0
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Percentilene beregnes fra de siste 1000 forespørslene per rute.
|
|
|
|
### queue_depth
|
|
|
|
Sanntidsstatus fra `job_queue`-tabellen:
|
|
|
|
```json
|
|
{
|
|
"pending": 3,
|
|
"running": 1,
|
|
"error": 0,
|
|
"retry": 1,
|
|
"completed_last_hour": 42
|
|
}
|
|
```
|
|
|
|
### ai_cost
|
|
|
|
Aggregerte AI-kostnader fra `ai_usage_log` for tre tidsperioder
|
|
(siste time, 24 timer, 30 dager):
|
|
|
|
```json
|
|
{
|
|
"last_hour": {
|
|
"requests": 5,
|
|
"input_tokens": 12000,
|
|
"output_tokens": 3000,
|
|
"estimated_cost_usd": 0.08
|
|
}
|
|
}
|
|
```
|
|
|
|
Kostnadsestimatet er basert på konservative gjennomsnittspriser
|
|
($3/MTok input, $15/MTok output).
|
|
|
|
## Request-logging middleware
|
|
|
|
Alle HTTP-forespørsler logges med:
|
|
|
|
- `method` — HTTP-metode
|
|
- `path` — Forespørsels-sti
|
|
- `status` — HTTP-statuskode
|
|
- `duration_ms` — Total responstid
|
|
|
|
Dette erstatter `tower_http::TraceLayer` med en mer strukturert
|
|
variant som også mater metrikk-samleren.
|
|
|
|
## Arkitektur
|
|
|
|
Metrikker samles i minnet (ingen ekstern avhengighet som Prometheus).
|
|
Designvalg:
|
|
|
|
- **Enkel:** Ingen nye avhengigheter eller ekstern infrastruktur
|
|
- **Tilstrekkelig:** Queue depth og AI-kostnad fra PG, latency in-memory
|
|
- **Utvidbar:** Kan legge til Prometheus-eksport senere ved behov
|