# Logning

## Hvad det er

Logning, også kaldet hændelseslogning, er et program, der løbende fører regnskab
med sin egen opførsel, én post pr. hændelse: en forespørgsel besvaret, en
adgangskode afvist, et genforsøg, et nedbrud. Hver post, en loglinje eller
logpost, bærer mindst et tidspunkt og en besked, så nogen bagefter kan stykke
sammen, hvad der skete, og i hvilken rækkefølge. OpenTelemetry-projektet
definerer en log som en tekstpost med tidsstempel, struktureret eller
ustruktureret, med valgfrie metadata, og bemærker, at af alle
telemetrisignalerne har logge den største arv.

Den arv har en standard. Syslog, den mangeårige protokol til at sende
hændelsesbeskeder videre til en opsamler, blev standardiseret i marts 2009 som
RFC 5424, der erstatter den ældre RFC 3164, og den giver hver besked én af otte
alvorsgrader, fra 0 for Emergency til 7 for Debug. De fleste logbiblioteker har
en kortere stige med samme idé: debug, info, warning, error. OpenTelemetrys
logdatamodel lægger dem alle ind på ét tal fra 1 til 24, i seks bånd fra TRACE
til FATAL.

En ustruktureret linje er fri tekst: let for et menneske at læse, og noget en
maskine kun kan skille ad med et regulært udtryk skrevet til netop den ordlyd.
En struktureret linje følger et skema, så hver post har de samme navngivne
felter med de samme typer og betydninger. OpenTelemetry foretrækker
strukturerede logge i produktion og tilføjer en advarsel, der er let at overse:
en linje kodet som JSON er ikke struktureret, blot fordi den kan parses; det,
der gør den struktureret, er et stabilt skema. Her vist over flere linjer er en
struktureret post én linje på disken:

```json
{
    "time": "2026-09-14T03:12:07.412Z",
    "severity": "WARN",
    "service": "checkout",
    "event": "payment.retry",
    "attempt": 3,
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
```

Metrikker og traces er de signaler, der normalt samles ind ved siden af.
Metrikker er tal målt over tid, billige at gemme og gode til at sige, hvor tit
noget sker. Traces følger én forespørgsel gennem hver tjeneste, den berører. En
log gemmer detaljen i de enkelte hændelser, og derfor er den det, nogen læser
efter en alarm for at finde ud af hvorfor. OpenTelemetry binder logge til traces
ved at hæfte id'erne for den aktive trace og det aktive span på hver logpost.

## Hvorfor det betyder noget

En log er den eneste beretning om fortiden, de fleste systemer efterlader sig.
En metrik kan sige, at fejlene steg kl. 03.12; loggen siger hvilken
forespørgsel, fra hvilken tjeneste, med hvilken værdi, og hvad programmet gjorde
bagefter. Når noget går i stykker om natten og er kommet sig om morgenen, er
loggen det vidne, der stadig er der.

Den beretning har en pris, som betales på tre måder. Hver linje koster disk,
input og output og processortid, og mere endnu, hvis den sendes til et centralt
lager, hvor en hostet tjeneste typisk tager betaling efter den mængde, der
modtages. Hver linje er også data om nogen: en webservers adgangslog rummer
adresser og browsere for alle, der har kaldt den. Og hver linje skal beskyttes.
OWASP's Logging Cheat Sheet beder om, at hver hændelse registrerer hvornår,
hvor, hvem og hvad, og at selve loggene beskyttes mod manipulation og mod
uautoriseret adgang, ændring og sletning, fordi de kan indeholde
personoplysninger og andre følsomme oplysninger.

I en organisations målestok behandler NIST Special Publication 800-92, Guide to
Computer Security Log Management af Karen Kent og Murugiah Souppaya, udgivet i
september 2006, loghåndtering som infrastruktur og processer på tværs af hele
virksomheden frem for en indstilling i ét program.

Logge virker også bedst ved siden af tal. Prometheus-projektets vejledning om
instrumentering foreslår en tæller for hver linje logkode, så man, når en
interessant besked dukker op, kan se, hvor tit den er sket, og hvor længe, og
foreslår at sammenligne antallet af info-, warning- og error-linjer fra én
udgivelse til den næste.

## Sådan ser det ud i praksis

Sitets egen adgangslog er beskrevet linje for linje på
[siden om privatliv](/da/privacy/). Hver forespørgsel registrerer siden og
tidspunktet, svarets status, browserens beskrivelse af sig selv, navnet på det
site, der henviste, og en sløret netværksadresse: den sidste del erstattes med
nuller i det øjeblik, linjen skrives, før noget rører disken. En linje lever i
omkring tredive dage. Filer roteres ved omkring 10 MB, og en roteret fil
slettes, når der findes fjorten nyere, eller når den bliver tredive dage gammel,
og den regel havde et hul: de stille adresser fyldte 10 MB så langsomt, at deres
filer aldrig var blevet roteret og stadig rummede hver linje, siden logningen
blev slået til. Et dagligt job lukker nu enhver fil, hvis ældste linje er mere
end et døgn gammel, og sletter lukkede filer efter tredive dage. Fire adresser
var i den gamle tilstand, og siden siger det.

På en macOS-applikation var logning én af tre årsager til, at
[hukommelsen blev fyldt med omkring 41 MB i sekundet](/da/portfolio/stopped-an-application-filling-memory-at-41mb-a-second-155/).
Hver hændelse frembragte loglinjer, så logningens omfang fulgte omfanget af det,
der gik galt, og én kort session skrev 610.996 af dem. Før styresystemet greb
ind, lå der 111 GB komprimerede sider på en bærbar med 36 GB. Med afgrænsede
hændelsesbuffere, abonnement efter hændelsestype og et logbudget, der slår
gentagelser sammen, skriver den samme session nu 1.411 linjer. Siden er ligefrem
om prisen: når noget går galt hurtigt nu, er optegnelsen over det bevidst
ufuldstændig.

På en produktionsvært fandt en
[hærdning af tretten systemd-units](/da/portfolio/cut-systemd-sandbox-exposure-across-every-unit-119/)
ét direktiv, der var stavet forkert i tre unit-skabeloner, så længe de roller
havde eksisteret. Servicemanageren svarer på en nøgle, den ikke genkender, ved
at logge det og starte unitten alligevel, så det eneste spor af fejlen var en
advarsel i en log; den kom frem, mens unittene blev skrevet om. Nu kører hver
unit gennem servicemanagerens egen verifikator under hver konvergering, så den
samme stavefejl stopper en kørsel.

## Hvor det går galt

**Loggen vokser hurtigst, når systemet allerede er ved at gå ned.** En løkke,
der logger hvert genforsøg, skriver en håndfuld linjer på en god dag og tusinder
i sekundet på en dårlig og tager disk, hukommelse og processortid fra et system,
der intet har at give af. OWASP beder teams efterprøve, at logning ikke kan
bruges til at opbruge systemets ressourcer, for eksempel ved at fylde disken.
Giv hver varm sti et budget, slå gentagne beskeder sammen til én linje med et
antal, og hold en tæller ved siden af beskeden, så raten overlever, når linjer
smides væk.

**Hemmeligheder og personoplysninger bliver skrevet ned.** En forespørgsel, der
logges hel, bærer alt det med, der var i den. OWASP's liste over det, der som
regel bør fjernes, maskeres, hashes eller krypteres, før det når en log,
omfatter sessions-id'er, adgangstokens, adgangskoder, forbindelsesstrenge til
databaser, krypteringsnøgler og betalingskortdata. Gør det, når linjen skrives,
som adgangsloggen ovenfor gør med adresser, for når nogen når at rydde op, kan
linjen allerede ligge i en sikkerhedskopi eller et arkiv.

**Input udefra skriver en falsk linje.** En værdi fra en bruger, der indeholder
et vognretur- eller linjeskifttegn og skrives uescapet ind i en tekstlog, kan
begynde en ny linje, der ligner en, applikationen selv skrev, på en prik. OWASP
kalder det log injection og beder om, at sådanne tegn renses, og at data kodes
til det format, de skrives i. En struktureret logger, der skriver hver værdi som
en escapet JSON-streng, gør det af sig selv.

**En log, der tier, ligner et sundt system.** En fuld disk, en roteret fil,
programmet aldrig åbnede igen, eller en opsamler, der gik ned, ser ens ud
udefra: linjerne holder op med at komme. OWASP beder om en måde at opdage, at
logningen er gået i stå. Tæl linjer pr. minut for hver kilde, og slå alarm, når
et antal falder til nul, så et hul i loggen bliver en alarm i sig selv.

## Læs mere

- [Logs](https://opentelemetry.io/docs/concepts/signals/logs/) — OpenTelemetry
  om, hvad en log er, hvorfor strukturerede logge foretrækkes, og hvordan logge
  bindes til traces.
- [Logs Data Model](https://opentelemetry.io/docs/specs/otel/logs/data-model/) —
  felterne i en logpost, dens to tidsstempler og alvorsskalaen fra 1 til 24.
- [RFC 5424: The Syslog Protocol](https://www.rfc-editor.org/rfc/rfc5424) —
  syslog-beskedformatet og dets otte alvorsgrader.
- [NIST SP 800-92](https://csrc.nist.gov/pubs/sp/800/92/final) — Guide to
  Computer Security Log Management.
- [Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)
  — OWASP om, hvilke hændelser der skal registreres, hvilke data der skal holdes
  ude, og hvordan resultatet beskyttes.
- [Instrumentation](https://prometheus.io/docs/practices/instrumentation/) —
  Prometheus-projektets praksis for at instrumentere kode, logning medregnet.

<https://engineer.company/da/glossary/logging/>
