synops/docs/infra/observerbarhet.md
vegard 0012a10373 Observerbarhet: strukturert logging, metrikker, /metrics-endepunkt (oppgave 12.1)
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.
2026-03-18 11:01:36 +00:00

2.2 KiB

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

{"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):

{
  "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:

{
  "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):

{
  "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