Web- en applicatielogs op grote schaal parseren
Haal statuscodes, latenties en clientvelden uit accesslogs met grep, cut en awk.
Web- en applicatielogs op grote schaal parseren is een gratis DevOps-bootcamp-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject DevOps-bootcamp. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Wat is een webtoegangslog?
Elke HTTP-server — Apache, Nginx, Caddy — schrijft voor elk verzoek één regel naar een toegangslog. Inzicht in de structuur van deze regels vormt de basis van alle werkzaamheden voor loganalyse.
Een typische regel in het Combined Log Format (CLF) ziet er zo uit:
- IP-adres van de client — wie het verzoek heeft gedaan
- Tijdstempel — wanneer het gebeurde
- Verzoekregel — methode, pad, protocol
- Statuscode — HTTP-antwoord (200, 404, 500…)
- Verzonden bytes — grootte van de antwoordtekst
- Referer — oorspronkelijke pagina
- User-Agent — tekenreeks van de browser of bot
Voorbeeldregel uit /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"
Op grote schaal groeien deze bestanden tot miljoenen regels per dag. Het doel van deze les is om velden er efficiënt uit te halen, te filteren en te aggregeren met standaardgereedschappen van BASH.
Een live log bekijken met tail en grep
Inspecteer de log voordat je een pijplijn schrijft, zodat je de structuur begrijpt. Met tail kun je een live gegevensstroom bekijken; grep beperkt die onmiddellijk tot relevante regels.
Veelgebruikte patronen:
tail -n 1000 access.log— de laatste 1000 regelstail -f access.log— in realtime volgentail -f access.log | grep '" 5'— alleen 5xx-fouten zodra ze binnenkomen
Het belangrijkste inzicht is dat grep zoekt in de volledige regel, dus het is belangrijk om je patroon te verankeren. Zo voorkom je met ' 500 ' (met spaties) dat je per ongeluk een URL-pad vindt waarin de tekenreeks 500 voorkomt.
#!/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] 'De statuscode extraheren met cut
cut splitst elke regel op basis van een scheidingsteken en drukt geselecteerde velden af. In het Combined Log Format staat de statuscode in veld 9 wanneer je op spaties splitst — maar door de aanhalingstekens rond de verzoekregel is het veiliger om vanaf een bekend anker te tellen.
Een betrouwbare truc: omdat de verzoekregel altijd tussen aanhalingstekens staat, is de statuscode altijd het eerste token na het afsluitende aanhalingsteken van het verzoekveld. Met cut -d'"' -f3 isoleer je alles na het aanhalingsteken van het verzoek; vervolgens selecteert een tweede cut -d' ' -f2 de statuscode.
Deze tweestapsbewerking met cut is een klassieke werkwijze voor CLF-logs — snel en zonder externe afhankelijkheden.
#!/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 -rnStatuscodes tellen met awk
awk is krachtiger dan cut, omdat het status over meerdere regels heen kan bijhouden. Het gebruikelijke patroon om voorkomens te tellen is een associatieve array met als sleutel de waarde waarin je geïnteresseerd bent.
In CLF is veld $9 (op 1 gebaseerd en door spaties gescheiden) de statuscode. awk verwerkt elke regel, verhoogt een teller en drukt vervolgens een gesorteerd overzicht af in het END-blok.
Waarom zou je awk verkiezen boven cut | sort | uniq -c? Omdat awk dit in één enkele doorgang doet, zonder eerst het volledige bestand te sorteren — cruciaal wanneer de log honderden gigabytes groot is.
#!/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 -rnFouten filteren en IP-adressen van clients extraheren
Een van de meest voorkomende operationele taken is bepalen welke IP-adressen van clients de meeste fouten veroorzaken. Hierbij combineer je filteren (alleen foutregels) met velden extraheren (het IP-adres in veld 1).
De pijplijnstrategie:
- Gebruik
awkom in één stap op het statuscodebereik te filteren en het IP-adres te extraheren — vermijd een apartegrep-doorgang - Stuur de uitvoer door naar
sort | uniq -c | sort -rn | headvoor snel overzicht van de bovenste resultaten
Dit patroon is snel genoeg om op één server uit te voeren voor een logbestand van 10 GB, zonder het bestand in het geheugen te laden.
#!/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 -10Reactievertraging uit applicatielogs parseren
Applicatieservers (Rails, Gunicorn, Express met morgan enzovoort) loggen vaak de duur van verzoeken. Nginx kan zo worden geconfigureerd dat het $request_time als extra veld aan het einde van elke regel uitvoert.
Een voorbeeld van een aangepaste Nginx-logindeling in nginx.conf:
log_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" rt=$request_time';
Zodra de vertraging in de log staat, kun je awk gebruiken om het gemiddelde, het maximum en percentielschattingen te berekenen over miljoenen verzoeken, zonder de gegevens in een database te laden.
#!/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.logEen histogram van reactievertragingen maken met awk
Een enkel gemiddelde verbergt staartvertraging. Een histogram laat de verdeling zien — of de meeste verzoeken snel zijn en enkele zeer traag (lange staart), of dat de verdeling gelijkmatig is.
De truc is om elke waarde met gehelegetallenrekenkunde in awk in een afgerond bereik te plaatsen. Door met 1000 te vermenigvuldigen (seconden omzetten naar milliseconden) en vervolgens gehelegetallendeling te gebruiken, krijg je duidelijke bereikgrenzen.
Dit levert een tekstueel histogram op dat je rechtstreeks in een terminal kunt lezen. Dat is vaak sneller dan gegevens naar Grafana sturen voor een snel onderzoek.
#!/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 -nUser-Agent extraheren en bots detecteren
Het User-Agent-veld (veld 6 wanneer je splitst op ") identificeert clients. Crawlers, scrapers en schadelijke bots vervuilen vaak je meetgegevens en verhogen de foutaantallen. Door ze eruit te filteren krijg je een zuiverder beeld van verkeer van echte gebruikers.
Veelvoorkomende botsignaturen: bot, crawler, spider, curl, python-requests, Googlebot, Bingbot.
Gebruik grep -iv (hoofdletterongevoelig omgekeerd zoeken) om bekende bots uit te sluiten, of gebruik awk om te splitsen op " en rechtstreeks overeenkomsten te zoeken in het UA-veld.
#!/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 -15Verkeer per eindpunt aggregeren
Weten welke eindpunten het meeste verkeer ontvangen — en de meeste fouten veroorzaken — helpt bij het prioriteren van optimalisatie en capaciteitsplanning. Het verzoekpad staat in het verzoekveld tussen aanhalingstekens.
Splits op ", neem veld 2 (de verzoekregel) en verwijder vervolgens de methode en het protocol om alleen het pad over te houden. Voor API's met padparameters zoals /users/12345 wil je ID's mogelijk ook normaliseren naar /users/:id met sed of een complexer awk-patroon.
#!/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 -20Fouten met eindpunten correleren met awk
De krachtigste analyse in één doorgang combineert meerdere velden tegelijk: eindpunt, statuscode en eventueel reactievertraging. Associatieve arrays van awk met samengestelde waarden als sleutel maken dit overzichtelijk en snel.
Het onderstaande patroon telt 5xx-fouten per eindpunt in één doorgang — zonder tijdelijke bestanden en zonder tussentijdse sorteringen tot helemaal aan het einde. Dit is de aanpak die in scripts voor productie-observeerbaarheid wordt gebruikt wanneer je op een grote log binnen een minuut antwoorden nodig hebt.
#!/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 -20Geroteerde en gecomprimeerde logs verwerken
Op de meeste servers worden logs dagelijks geroteerd. Oudere bestanden worden met gzip gecomprimeerd als access.log.1.gz, access.log.2.gz enzovoort. Standaardgereedschappen kunnen ze niet rechtstreeks lezen, maar twee aanpakken werken goed:
zcat— decomprimeert naar stdout en stuurt de uitvoer door naar je pijplijnzgrep— zoekt rechtstreeks in gzip-bestanden zonder ze uit te pakken
Gebruik voor analyse van een volledige week aan logs uit zowel ongecomprimeerde als gecomprimeerde bestanden proces-substitutie of voeg bestanden samen met zcat. Het onderstaande fragment verwerkt de laatste 7 geroteerde bestanden plus de huidige live log in één aanroep van awk — tijdelijke bestanden zijn niet nodig.
#!/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 -rnIn welk awk-veld staat de HTTP-statuscode in het Combined Log Format?
Je schrijft een awk-one-liner om alleen HTTP 4xx-reacties uit een standaard Nginx-toegangslogboek in Combined Log Format te filteren (gescheiden door spaties, waarbij de aanvraagregel tussen aanhalingstekens staat). Welk veldnummer identificeert de HTTP-statuscode correct?
Samenvatting van de les: pijplijnen voor loganalyse
In deze les heb je met alleen standaardhulpprogramma's van BASH een complete gereedschapskist opgebouwd voor het op grote schaal analyseren van web- en applicatielogboeken.
Belangrijkste behandelde technieken:
- Eerst de structuur — Combined Log Format heeft een voorspelbare veldindeling; als je die kent, kun je de invoer betrouwbaar opsplitsen met
cut -d'"'of veldverwijzingen inawk. - Statuscodes extraheren —
awk '{ count[$9]++ }'telt alle codes in één doorgang; filter met$9 ~ /^5/op serverfouten. - Latentieanalyse — verwerk het aangepaste veld
rt=metawkom gemiddelden, maximumwaarden en histogramintervallen te berekenen zonder extern hulpmiddel. - Analyse van clients en bots — splits op
"met-F'"'om het User-Agent-veld te bereiken; leid de uitvoer doorgrep -ivom bots uit te sluiten voordat je gaat aggregeren. - Eindpunten normaliseren — gebruik
gsub(/\/[0-9]+/, "/:id")binnenawkom paden met parameters samen te voegen voordat je gaat tellen. - Geroteerde logboeken — combineer
catenzcatin een subshell om alle bestanden met logboekrotaties in één pijplijndoorgang te verwerken.
Deze patronen kunnen worden gecombineerd: je kunt filteren, extraheren, normaliseren en aggregeren in één pijplijn die honderden miljoenen regels verwerkt op gangbare hardware. Als je deze basisbouwstenen beheerst, heb je voor ad-hoc onderzoek van incidenten zelden een speciale service voor logboekaggregatie nodig.
Leer DevOps-bootcamp met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 142
- Lessen
- 568
Veelgestelde vragen
Is de les “Web- en applicatielogs op grote schaal parseren” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad DevOps-bootcamp, waaronder “Web- en applicatielogs op grote schaal parseren”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Wat leer ik in “Web- en applicatielogs op grote schaal parseren”?
Haal statuscodes, latenties en clientvelden uit accesslogs met grep, cut en awk. Je oefent met DevOps-bootcamp door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met DevOps-bootcamp te beginnen?
Ervaring vooraf is niet nodig. DevOps-bootcamp op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Web- en applicatielogs op grote schaal parseren”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over DevOps-bootcamp?
Ja. Elke les over DevOps-bootcamp bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Web- en applicatielogs op grote schaal parseren
- Logs in realtime volgen en streamingwaarschuwingen
- journald doorzoeken met journalctl in scripts
- Statistieken en histogrammen uit logstreams berekenen