Linux-kommandolinjen og Bash-scripting på ekspertniveau · Lektion

Beregning af metrikker og histogrammer fra logstreams

Aggregér forespørgselsrater, percentiler og top-N-rapporter direkte fra streamede logdata.

Lektion 4 af 413 trin

Beregning af metrikker og histogrammer fra logstreams er en gratis Linux-kommandolinjen og Bash-scripting på ekspertniveau-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Linux-kommandolinjen og Bash-scripting på ekspertniveau, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Linux-kommandolinjen og Bash-scripting på ekspertniveau-kurset indeholder 4 lektioner i alt.

Hvorfor beregne målepunkter ud fra rå logfiler?

Produktionssystemer udsender tusindvis af loglinjer pr. sekund. I stedet for at sende rå logfiler til dyre analyseplatforme kan du beregne forespørgselsrater, percentiler og top-N-rapporter direkte i shellen — til næsten ingen omkostninger.

  • Forespørgselsrate: Hvor mange forespørgsler pr. sekund/minut håndterer din tjeneste?
  • Percentiler for latenstid: Hvad er svartiden ved p50/p95/p99?
  • Top-N-rapporter: Hvilke slutpunkter, IP-adresser eller fejlkoder forekommer hyppigst?

Shellværktøjer som awk, sort, uniq og bc udgør en effektiv, sammensættelig datapipeline, der kan besvare disse spørgsmål ud fra en live logstrøm eller en historisk fil uden at forlade terminalen.

Opbygningen af en almindelig adgangslog

De fleste webservere skriver logfiler i Combined Log-format. At forstå felterne er grundlaget for enhver pipeline til målepunkter:

127.0.0.1 - frank [10/Oct/2024:13:55:36 -0700] "GET /api/users HTTP/1.1" 200 2326 0.042
  • Felt 1: klientens IP-adresse
  • Felt 4 (i kantede parenteser): tidsstempel
  • Felt 7 (i citationstegn): HTTP-metode + sti
  • Felt 9: statuskode
  • Felt 10: svartidens antal bytes
  • Felt 11: svartid i sekunder (brugerdefineret felt, ikke altid til stede)

Brug awk til at referere til felter efter deres position ($1, $9 osv.). Felter i citationstegn tæller kun som ét token, hvis du opdeler omhyggeligt — omslut loglinjen med awk -F'"', eller brug flere gennemløb.

Optælling af forespørgselsrate pr. minut

For at beregne forespørgsler pr. minut skal du udtrække minutdelen af hvert tidsstempel og tælle forekomsterne. Mønsteret [day/Mon/year:HH:MM giver dig time-minut-gruppen.

Datapipelinen nedenfor læser access.log og udskriver en tabel med minut → antal forespørgsler:

#!/usr/bin/env bash
# Requests per minute from an nginx/apache access log
# Usage: bash req_per_min.sh access.log

LOG="${1:-access.log}"

awk '{
    # Extract [day/Mon/year:HH:MM from field 4
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    minute = arr[1]
    if (minute != "") count[minute]++
} END {
    for (m in count) print count[m], m
}' "$LOG" | sort -k2

Rate i et glidende vindue med en live strøm

Til en live følgevisning har du brug for et glidende vindue. Tricket er at pipe tail -f ind i awk, som nulstiller tælleren hvert N. sekund ved hjælp af systemuret (systime()).

Dette eksempel udskriver en ratelinje hvert 10. sekund:

#!/usr/bin/env bash
# Live request rate — prints lines/10s from a tailed log
# Usage: bash live_rate.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
WINDOW=10

tail -f "$LOG" | awk -v win="$WINDOW" '
BEGIN { start = systime(); count = 0 }
{
    count++
    now = systime()
    if (now - start >= win) {
        printf "[%s] %d req/%ds (%.1f req/s)\n",
               strftime("%H:%M:%S", now), count, win, count/win
        count = 0
        start = now
    }
}'

Udtræk af latenstidsværdier til beregning af percentiler

Percentiler kræver, at alle observerede latenstidsværdier sorteres. Standardfremgangsmåden er:

  1. Udtræk latenstidskolonnen til en liste med rene tal.
  2. Sortér numerisk.
  3. Vælg værdien på den korrekte rang ved hjælp af matematik baseret på antallet af linjer.

Scriptet nedenfor udtrækker felt 11 (svartid i sekunder) og gemmer det i en midlertidig fil til beregning af percentiler i næste trin:

#!/usr/bin/env bash
# Extract latency column from access log (field 11)
# Assumes last field on each line is response time in seconds

LOG="${1:-access.log}"
TMP=$(mktemp /tmp/latency_XXXXXX.txt)

awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF }' "$LOG" \
    | sort -n > "$TMP"

echo "Extracted $(wc -l < "$TMP") latency samples -> $TMP"
echo "$TMP"   # callers can read this file

Beregning af p50, p95 og p99 med awk

Når latenstidsværdierne er sorteret, er det aritmetik at vælge en percentil: Den p. percentil ligger på række ceil(p/100 * N). Ren awk kan gøre dette i ét gennemløb efter at have indlæst den sorterede fil i et array:

#!/usr/bin/env bash
# Compute p50 / p95 / p99 from a sorted latency file
# Usage: bash percentiles.sh latency_sorted.txt

# Demo: generate 1000 random latencies if no file given
if [[ $# -eq 0 ]]; then
    SORTED=$(mktemp)
    for i in $(seq 1 1000); do
        awk 'BEGIN { srand(); printf "%.4f\n", 0.001 + rand()*0.999 }'
    done | sort -n > "$SORTED"
else
    SORTED="$1"
fi

awk '
{ values[NR] = $1 }
END {
    n = NR
    if (n == 0) { print "No data"; exit }
    p50  = values[int(n * 0.50 + 0.9999)]
    p95  = values[int(n * 0.95 + 0.9999)]
    p99  = values[int(n * 0.99 + 0.9999)]
    printf "p50  = %.4fs\np95  = %.4fs\np99  = %.4fs\nN    = %d\n",
           p50, p95, p99, n
}' "$SORTED"

Opbygning af en rapport over top-N-slutpunkter

En top-N-rapport besvarer spørgsmålet »hvilke stier rammes oftest?«. Det klassiske shell-idiom er:

  • awk til at udskrive det relevante felt (for eksempel URL-stien)
  • sort til at gruppere identiske værdier
  • uniq -c til at tælle efterfølgende dubletter
  • sort -rn til at rangordne efter faldende antal
  • head -n N til at udvælge de øverste N
#!/usr/bin/env bash
# Top-10 most requested URL paths from access log
# Usage: bash top_endpoints.sh access.log [N]

LOG="${1:-access.log}"
N="${2:-10}"

echo "=== Top $N endpoints ==="
awk -F'"' '{ print $2 }' "$LOG" \
    | awk '{ print $2 }' \
    | sort \
    | uniq -c \
    | sort -rn \
    | head -n "$N" \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

Top-N efter statuskode: Find fejl med et blik

HTTP-statuskoder fortæller dig, om din tjeneste er sund. Ved at gruppere loglinjer efter statuskode og tælle dem kan du se, om fejl er sjældne eller systematiske.

Scriptet nedenfor genererer en opdeling på tværs af alle 2xx-/3xx-/4xx-/5xx-grupper:

#!/usr/bin/env bash
# Status code frequency breakdown
# Usage: bash status_breakdown.sh access.log

LOG="${1:-access.log}"

echo "=== HTTP Status Code Distribution ==="
awk '{ print $9 }' "$LOG" \
    | grep -E '^[0-9]{3}$' \
    | sort \
    | uniq -c \
    | sort -rn \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

echo
echo "=== 5xx Error Spike Check ==="
awk '$9 ~ /^5/ { print $9, $7 }' "$LOG" \
    | sort | uniq -c | sort -rn | head -20

ASCII-histogrammer med awk

Et teksthistogram gør latenstidsfordelinger umiddelbart læselige i en terminal eller CI-log. Fremgangsmåden er:

  1. Placer hver latenstidsværdi i en gruppe (for eksempel 0-50 ms, 50-100 ms, …).
  2. Tæl observationerne i hver gruppe.
  3. Udskriv en søjle med #-tegn skaleret efter det maksimale antal.

Det er særdeles nyttigt til at finde bimodale fordelinger eller afvigere uden et værktøj til graftegning.

#!/usr/bin/env bash
# ASCII latency histogram from a list of latency values in seconds
# Demo: generates synthetic data if no input file is provided

if [[ $# -eq 0 ]]; then
    # Generate 500 synthetic latencies (ms converted to s)
    python3 -c "
import random, math
for _ in range(500):
    # bimodal: fast cluster ~50ms, slow cluster ~300ms
    if random.random() < 0.75:
        v = max(1, random.gauss(50, 15))
    else:
        v = max(1, random.gauss(300, 80))
    print(f'{v/1000:.4f}')
" | sort -n | awk '
{ values[NR] = $1 * 1000 }  # convert to ms
END {
    buckets = 10; maxVal = 500
    step = maxVal / buckets
    for (i = 0; i < buckets; i++) hist[i] = 0
    for (i = 1; i <= NR; i++) {
        b = int(values[i] / step)
        if (b >= buckets) b = buckets - 1
        hist[b]++
    }
    maxCount = 0
    for (i = 0; i < buckets; i++) if (hist[i] > maxCount) maxCount = hist[i]
    print "Latency (ms)   Count   Distribution"
    print "---------------------------------------"
    for (i = 0; i < buckets; i++) {
        lo = i * step; hi = lo + step
        barLen = int(hist[i] / maxCount * 40)
        bar = ""
        for (j = 0; j < barLen; j++) bar = bar "#"
        printf "%4d-%4dms  %5d  %s\n", lo, hi, hist[i], bar
    }
}'
else
    echo "Usage: pipe a sorted latency file (in seconds) to this pattern"
fi

Kombination af målepunkter: Samlerapport med én kommando

Runbooks til produktion har ofte brug for én kommando, der udskriver alle vigtige målepunkter på én gang: rate, latenstidspercentiler, top-slutpunkter og fejlrate. Du kan samle alt det, du har lært indtil videre, i ét script, som et menneske eller et alarmeringssystem kan kalde.

#!/usr/bin/env bash
# One-shot log summary report
# Usage: bash log_summary.sh access.log

LOG="${1:-access.log}"
[[ -f "$LOG" ]] || { echo "File not found: $LOG"; exit 1; }

TOTAL=$(wc -l < "$LOG")
ERRORS=$(awk '$9 ~ /^[45]/' "$LOG" | wc -l)
ERR_RATE=$(awk "BEGIN { printf \"%.1f\", ($ERRORS / ($TOTAL || 1)) * 100 }")

echo "====================================="
echo " Log Summary: $LOG"
echo "====================================="
printf " Total requests : %d\n" "$TOTAL"
printf " 4xx/5xx errors : %d (%.1f%%)\n" "$ERRORS" "$ERR_RATE"

echo
echo "--- Top 5 Endpoints ---"
awk -F'"' '{ print $2 }' "$LOG" | awk '{ print $2 }' \
    | sort | uniq -c | sort -rn | head -5 \
    | awk '{ printf "  %6d  %s\n", $1, $2 }'

echo
echo "--- Latency Percentiles ---"
awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF * 1000 }' "$LOG" \
    | sort -n \
    | awk '
{ v[NR]=$1 }
END {
  if (NR==0) { print "  No latency data"; exit }
  printf "  p50 = %.1fms\n", v[int(NR*0.50+0.9999)]
  printf "  p95 = %.1fms\n", v[int(NR*0.95+0.9999)]
  printf "  p99 = %.1fms\n", v[int(NR*0.99+0.9999)]
}'

Streaming af målepunkter via navngivne pipes og tee

I datapipelines til overvågningsdata har du ofte brug for at fordele en logstrøm: skrive rå linjer til disken og samtidig beregne målepunkter. tee sammen med en navngiven pipe (mkfifo) gør dette muligt uden at gemme hele strømmen i hukommelsen.

  • mkfifo /tmp/log_pipe — opret den navngivne pipe
  • tee /tmp/log_pipe | metric_consumer & — forgren én gren til forbrugeren af målepunkterne
  • Den anden gren skriver til arkivfilen

Dette mønster holder diskskrivning og sammenlægning af målepunkter adskilt og gør det muligt at genstarte hver side uafhængigt.

#!/usr/bin/env bash
# Fan-out: write to archive AND count errors in real time
# Run: bash fanout_pipeline.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
ARCHIVE="/tmp/access_archive.log"
PIPE="/tmp/log_metrics_pipe"

# Clean up on exit
trap 'rm -f "$PIPE"' EXIT

mkfifo "$PIPE"

# Branch 1: count 5xx errors per minute from the pipe
awk '$9 ~ /^5/ {
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    errors[arr[1]]++
} END {
    for (m in errors) printf "5xx errors at %s: %d\n", m, errors[m]
}' "$PIPE" &

# Branch 2: archive to disk + feed Branch 1 via pipe
tail -f "$LOG" | tee "$PIPE" >> "$ARCHIVE"

Hvilken awk-teknik beregner korrekt p95-percentilen fra et sorteret array med N latenstidsværdier?

Du har indlæst N sorterede latenstidsværdier i et awk-array v[1..N]. Hvilket udtryk henter korrekt p95-percentilen?

Opsummering af lektionen: Målinger og histogrammer fra logstrømme

I denne lektion har du opbygget en komplet målepipeline direkte i Bash:

  • Forespørgselsrate: awk udtrækker minutintervallet fra tidsstempler og tæller forekomster; tail -f + systime() giver en live-rate over et glidende tidsvindue.
  • Latenstidspercentiler: udtræk latenstidskolonnen, kør sort -n, og vælg derefter rækken ved ceil(p/100 * N) med int(N * p + 0.9999) i awk.
  • Top-N-rapporter: den klassiske awk | sort | uniq -c | sort -rn | head -N-pipeline fungerer for alle kategoriske felter (sti, IP-adresse, statuskode).
  • ASCII-histogrammer: opdel værdier i intervaller, tæl pr. interval, og skaler bjælkelængden efter det maksimale antal i et interval for at få et hurtigt overblik over fordelingen.
  • Fan-out med navngivne pipes: mkfifo + tee lader dig arkivere rå logge og samtidig føde måleforbrugere uden at indlæse strømmen i hukommelsen.

Disse komponerbare primitiver fjerner behovet for eksterne værktøjer under hændelser og udgør rygraden i lette scripts til observerbarhed, som kan køre overalt, hvor Bash kører.

Gratis at komme i gang

Lær Bash med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
22
Lektioner
88

Ofte stillede spørgsmål

Er lektionen “Beregning af metrikker og histogrammer fra logstreams” gratis?

Ja — hele teksten til “Beregning af metrikker og histogrammer fra logstreams” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Linux-kommandolinjen og Bash-scripting på ekspertniveau-kurset, skal du opgradere til CoddyKit PRO. Linux-kommandolinjen og Bash-scripting på ekspertniveau-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Beregning af metrikker og histogrammer fra logstreams”?

Aggregér forespørgselsrater, percentiler og top-N-rapporter direkte fra streamede logdata. Du øver dig i Linux-kommandolinjen og Bash-scripting på ekspertniveau med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Linux-kommandolinjen og Bash-scripting på ekspertniveau?

Der kræves ingen tidligere erfaring. Linux-kommandolinjen og Bash-scripting på ekspertniveau på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Beregning af metrikker og histogrammer fra logstreams”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Linux-kommandolinjen og Bash-scripting på ekspertniveau-lektion?

Ja. Alle Linux-kommandolinjen og Bash-scripting på ekspertniveau-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Parsing af web- og applikationslogs i stor skala
  2. Logovervågning i realtid og streaming-alarmer
  3. Forespørgsler til journald med journalctl i scripts
  4. Beregning af metrikker og histogrammer fra logstreams
← Tilbage til Linux-kommandolinjen og Bash-scripting på ekspertniveau