Mestring av Linux-kommandolinjen og Bash-skripting · leksjon

Analyse av nett- og applikasjonslogger i stor skala

Hent ut statuskoder, responstider og klientfelt fra tilgangslogger ved hjelp av grep, cut og awk.

Leksjon 1 av 413 trinn

Analyse av nett- og applikasjonslogger i stor skala er en gratis leksjon i Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Mestring av Linux-kommandolinjen og Bash-skripting, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hva er en webtilgangslogg?

Alle HTTP-servere – Apache, Nginx og Caddy – skriver én linje i en tilgangslogg for hver forespørsel. Å forstå strukturen i disse linjene er grunnlaget for alt arbeid med logganalyse.

En typisk linje i Combined Log Format (CLF) ser slik ut:

  • Klient-IP – hvem som sendte forespørselen
  • Tidsstempel – når det skjedde
  • Forespørselslinje – metode, sti og protokoll
  • Statuskode – HTTP-svaret (200, 404, 500…)
  • Sendte byte – størrelsen på svarinnholdet
  • Referer – kildesiden
  • User-Agent – streng som identifiserer nettleseren eller boten

Eksempel på en linje fra /var/log/nginx/access.log:

192.168.1.10 - alice [11/Jun/2026:14:32:01 +0000] "GET /api/orders HTTP/1.1" 200 1482 "-" "curl/7.88.1"

I stor skala vokser disse filene til millioner av linjer per dag. Målet med denne leksjonen er å hente ut, filtrere og aggregere felt fra dem effektivt ved hjelp av standardverktøy i BASH.

Slik undersøker De en live-logg med tail og grep

Før De skriver en pipeline, bør De undersøke loggen for å forstå strukturen. tail lar Dem følge en strøm i sanntid, mens grep umiddelbart begrenser den til relevante linjer.

Vanlige mønstre:

  • tail -n 1000 access.log – de siste 1000 linjene
  • tail -f access.log – følg loggen i sanntid
  • tail -f access.log | grep '" 5' – bare 5xx-feil etter hvert som de oppstår

Det viktige poenget er at grep sammenligner med hele linjen, så det er viktig å forankre mønsteret riktig. Ved å søke etter ' 500 ' (med mellomrom) unngår De å treffe en URL-sti som inneholder strengen 500 ved et uhell.

#!/usr/bin/env bash
# Watch only HTTP 5xx errors arriving in real time
tail -f /var/log/nginx/access.log \
  | grep --line-buffered '" 5[0-9][0-9] '

Hente ut statuskoden med cut

cut deler hver linje ved hjelp av et skilletegn og skriver ut valgte felt. I Combined Log Format ligger statuskoden i felt 9 når De deler på mellomrom – men anførselstegnene rundt forespørselslinjen gjør det tryggere å telle fra et kjent ankerpunkt.

Et pålitelig triks er at forespørselslinjen alltid står mellom anførselstegn. Statuskoden er derfor alltid det første tokenet etter det avsluttende anførselstegnet for forespørselsfeltet. Med cut -d'"' -f3 isolerer De alt etter anførselstegnet som avslutter forespørselen, og deretter henter et nytt cut -d' ' -f2 ut statuskoden.

Denne todelte cut-metoden er en klassisk idiom for CLF-logger – rask og uten eksterne avhengigheter.

#!/usr/bin/env bash
# Print only the HTTP status code from each log line
# Input format: ... "GET /path HTTP/1.1" 200 1482 ...
cut -d'"' -f3 /var/log/nginx/access.log \
  | cut -d' ' -f2 \
  | sort \
  | uniq -c \
  | sort -rn

Telle statuskoder med awk

awk er kraftigere enn cut fordi det kan samle tilstand på tvers av linjer. Det idiomatiske mønsteret for å telle forekomster er en assosiativ tabell med nøkkel basert på verdien De ønsker å telle.

I CLF er felt $9 (indeksert fra 1 og avgrenset med mellomrom) statuskoden. awk behandler hver linje, øker en teller og skriver deretter ut et sortert sammendrag i END-blokken.

Hvorfor foretrekke awk fremfor cut | sort | uniq -c? Fordi awk gjør dette i én enkeltpassering uten å sortere hele filen først – noe som er avgjørende når loggen er på hundrevis av gigabyte.

#!/usr/bin/env bash
# Count HTTP status codes in a single awk pass
awk '{ count[$9]++ }
END {
  for (status in count)
    printf "%6d  %s\n", count[status], status
}' /var/log/nginx/access.log \
  | sort -rn

Filtrere feil og hente ut klient-IP-er

En av de vanligste driftsoppgavene er å finne ut hvilke klient-IP-er som genererer flest feil. Dette kombinerer filtrering (bare feillinjer) med felthenting (IP-adressen i felt 1).

Pipeline-strategien:

  • Bruk awk til å filtrere på statuskodeintervall og hente ut IP-adressen i ett trinn – unngå en separat grep-passering
  • Send resultatet videre med sort | uniq -c | sort -rn | head for å få en rask oversikt over de N øverste

Dette mønsteret er raskt nok til å kjøres mot en loggfil på 10 GB på én enkelt server uten å laste filen inn i minnet.

#!/usr/bin/env bash
# Top 10 IPs generating HTTP 4xx or 5xx errors
awk '$9 ~ /^[45][0-9][0-9]$/ { print $1 }' \
    /var/log/nginx/access.log \
  | sort \
  | uniq -c \
  | sort -rn \
  | head -10

Analysere svartid fra applikasjonslogger

Applikasjonsservere (Rails, Gunicorn, Express med morgan og lignende) logger ofte varigheten på forespørsler. Nginx kan konfigureres til å skrive ut $request_time som et ekstra felt på slutten av hver linje.

Eksempel på et egendefinert Nginx-loggformat i nginx.conf:

log_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" rt=$request_time';

Når svartiden finnes i loggen, kan De bruke awk til å beregne gjennomsnitt, maksimum og tilnærmede persentiler for millioner av forespørsler uten å laste dataene inn i en database.

#!/usr/bin/env bash
# Compute average and max request_time from Nginx timed log
# Assumes last field is rt=<seconds> e.g. rt=0.042
awk '{
  # Extract numeric value after rt=
  n = split($NF, a, "=")
  if (n == 2 && a[1] == "rt") {
    t = a[2] + 0
    sum += t
    count++
    if (t > max) max = t
  }
}
END {
  if (count > 0)
    printf "Requests: %d  Avg: %.4fs  Max: %.4fs\n", count, sum/count, max
}' /var/log/nginx/timed_access.log

Bygge et svartidshistogram med awk

Et enkelt gjennomsnitt skjuler haleforsinkelsen. Et histogram viser fordelingen – om de fleste forespørslene er raske og noen få er svært trege (en lang hale), eller om fordelingen er jevn.

Trikset er å plassere hver verdi i et avrundet intervall ved hjelp av heltallsaritmetikk i awk. Ved å multiplisere med 1000 (konvertere sekunder til millisekunder) og deretter bruke heltallsdivisjon får De tydelige intervallgrenser.

Resultatet er et tekstdrevet histogram som De kan lese direkte i en terminal. Det er ofte raskere enn å sende data til Grafana for en rask undersøkelse.

#!/usr/bin/env bash
# Latency histogram (50ms buckets) from Nginx timed log
awk '{
  n = split($NF, a, "=")
  if (n == 2 && a[1] == "rt") {
    ms = int(a[2] * 1000)      # convert to ms
    bucket = int(ms / 50) * 50 # round down to 50ms boundary
    hist[bucket]++
  }
}
END {
  for (b in hist)
    printf "%6dms  %d\n", b, hist[b]
}' /var/log/nginx/timed_access.log \
  | sort -n

Hente ut User-Agent og oppdage boter

User-Agent-feltet (felt 6 når De deler på ") identifiserer klientene. Crawlere, skrapere og ondsinnede boter forstyrrer ofte måleverdiene og blåser opp feiltallene. Ved å filtrere dem bort får De et tydeligere bilde av trafikken fra faktiske brukere.

Vanlige bot-signaturer: bot, crawler, spider, curl, python-requests, Googlebot, Bingbot.

Bruk grep -iv (invertert søk uten hensyn til store og små bokstaver) for å utelate kjente boter, eller bruk awk til å dele på " og sammenligne UA-feltet direkte.

#!/usr/bin/env bash
# Count top 15 User-Agent strings, excluding known bots
awk -F'"' '{ print $6 }' /var/log/nginx/access.log \
  | grep -iv -e 'bot' -e 'crawler' -e 'spider' -e 'curl' \
              -e 'python' -e 'wget' -e 'Go-http-client' \
  | sort \
  | uniq -c \
  | sort -rn \
  | head -15

Aggregere trafikk per endepunkt

Ved å vite hvilke endepunkter som mottar mest trafikk – og genererer flest feil – blir det enklere å prioritere optimalisering og kapasitetsplanlegging. Forespørselsstien ligger i det anførselstegninnrammede forespørselsfeltet.

Del på ", ta felt 2 (forespørselslinjen), og fjern deretter metode og protokoll for å isolere stien. For API-er med sti-parametere som /users/12345 kan De også ønske å normalisere ID-er til /users/:id ved hjelp av sed eller et mer komplekst awk-mønster.

#!/usr/bin/env bash
# Top 20 requested endpoints (method + path, no query string)
awk -F'"' '{ print $2 }' /var/log/nginx/access.log \
  | awk '{ print $1, $2 }' \
  | sed 's|/[0-9][0-9]*\b|/:id|g' \
  | sort \
  | uniq -c \
  | sort -rn \
  | head -20

Korrelelere feil med endepunkter ved hjelp av awk

Den kraftigste analysen i én enkelt passering kombinerer flere felt samtidig: endepunkt, statuskode og eventuelt svartid. Assosiative tabeller i awk med sammensatte nøkler gjør dette ryddig og raskt.

Mønsteret nedenfor teller 5xx-feil per endepunkt i én passering – uten midlertidige filer og uten mellomliggende sortering før helt til slutt. Dette er fremgangsmåten som brukes i produksjonsskript for observability når De trenger svar på under ett minutt fra en stor logg.

#!/usr/bin/env bash
# Count 5xx errors per endpoint path in a single pass
awk -F'"' '{
  # $2 = request line e.g. "GET /api/orders HTTP/1.1"
  # $0 in original space-split: $9 = status
  split($0, fields, " ")
  status = fields[9]
  if (status ~ /^5/) {
    split($2, req, " ")
    path = req[2]
    # Normalise numeric IDs
    gsub(/\/[0-9]+/, "/:id", path)
    errors[path]++
  }
}
END {
  for (p in errors)
    printf "%6d  %s\n", errors[p], p
}' /var/log/nginx/access.log \
  | sort -rn \
  | head -20

Behandle roterte og komprimerte logger

På de fleste servere roteres logger daglig. Eldre filer komprimeres med gzip og får navn som access.log.1.gz, access.log.2.gz og så videre. Standardverktøy kan ikke lese dem direkte, men to fremgangsmåter fungerer godt:

  • zcat – dekomprimerer til standardutdata, slik at De kan sende resultatet inn i pipelinen
  • zgrep – søker direkte i gzip-filer uten å pakke dem ut

Hvis De vil analysere en hel uke med logger som omfatter både ukomprimerte og komprimerte filer, kan De bruke prosessubstitusjon eller sette sammen filene med zcat. Utdraget nedenfor behandler de siste 7 roterte filene samt den aktive loggen i ett enkelt awk-kall – uten behov for midlertidige filer.

#!/usr/bin/env bash
# Aggregate status codes across a week of rotated logs
# Handles both plain and gzip-compressed rotation files

LOG_DIR="/var/log/nginx"

{
  cat  "${LOG_DIR}/access.log" 2>/dev/null
  zcat "${LOG_DIR}/access.log".*.gz 2>/dev/null
} | awk '
{ count[$9]++ }
END {
  for (s in count)
    printf "%6d  %s\n", count[s], s
}' | sort -rn

Hvilket awk-felt inneholder HTTP-statuskoden i Combined Log Format?

De skriver en awk-enlinjer for å filtrere ut bare HTTP 4xx-svar fra en standard Nginx-tilgangslogg i Combined Log Format (mellomromsseparert, med forespørselslinjen i anførselstegn). Hvilket feltnummer identifiserer HTTP-statuskoden korrekt?

Oppsummering av leksjonen: Pipelines for logganalyse

I denne leksjonen bygget De et komplett verktøysett for å analysere web- og applikasjonslogger i stor skala, kun ved hjelp av standardverktøy i BASH.

Viktige teknikker:

  • Start med strukturen — Combined Log Format har en forutsigbar feltstruktur. Når De kjenner den, kan De dele opp loggen pålitelig med cut -d'"' eller felthenvisninger i awk.
  • Hente ut statuskoder — awk '{ count[$9]++ }' teller alle kodene i én gjennomgang. Filtrer med $9 ~ /^5/ for serverfeil.
  • Analysere forsinkelse — tolk det egendefinerte rt=-feltet med awk for å beregne gjennomsnitt, maksimumsverdier og histogramintervaller uten eksterne verktøy.
  • Analysere klienter og boter — del på " med -F'"' for å komme til User-Agent-feltet. Send deretter resultatet gjennom grep -iv for å utelate boter før aggregering.
  • Normalisere endepunkter — bruk gsub(/\/[0-9]+/, "/:id") i awk for å slå sammen parametriserte stier før opptelling.
  • Roterte logger — kombiner cat og zcat i et subshell for å sende alle rotasjonsfilene gjennom én samlet pipeline.

Disse mønstrene kan kombineres: De kan kjede sammen filtrering, uthenting, normalisering og aggregering i én pipeline som behandler hundrevis av millioner linjer på standard maskinvare. Når De behersker disse grunnprinsippene, trenger De sjelden en dedikert loggaggregeringstjeneste for ad hoc-undersøkelser av hendelser.

Gratis å komme i gang

Lær deg Bash med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
88

Ofte stilte spørsmål

Er leksjonen «Analyse av nett- og applikasjonslogger i stor skala» gratis?

Ja – hele teksten i «Analyse av nett- og applikasjonslogger i stor skala» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Mestring av Linux-kommandolinjen og Bash-skripting-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hva lærer jeg i «Analyse av nett- og applikasjonslogger i stor skala»?

Hent ut statuskoder, responstider og klientfelt fra tilgangslogger ved hjelp av grep, cut og awk. Du øver på Mestring av Linux-kommandolinjen og Bash-skripting med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Mestring av Linux-kommandolinjen og Bash-skripting?

Ingen tidligere erfaring er nødvendig. Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.

Hvor lang tid tar leksjonen «Analyse av nett- og applikasjonslogger i stor skala»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Mestring av Linux-kommandolinjen og Bash-skripting-leksjonen?

Ja. Alle Mestring av Linux-kommandolinjen og Bash-skripting-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Analyse av nett- og applikasjonslogger i stor skala
  2. Sanntidsfølging av logger og strømmende varsler
  3. Spørring mot journald med journalctl i skript
  4. Beregning av måltall og histogrammer fra loggstrømmer
← Tilbake til Mestring av Linux-kommandolinjen og Bash-skripting