Analizzare log web e applicativi su larga scala
Estragga codici di stato, latenze e campi client dai log di accesso usando grep, cut e awk.
Analizzare log web e applicativi su larga scala è una lezione DevOps Bootcamp gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento DevOps Bootcamp, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso DevOps Bootcamp include 4 lezioni in totale.
Che cos'è un log degli accessi web?
Ogni server HTTP — Apache, Nginx, Caddy — scrive una riga in un log degli accessi per ogni richiesta. Comprendere la struttura di queste righe è il fondamento di qualsiasi attività di analisi dei log.
Una riga tipica nel Combined Log Format (CLF) è simile alla seguente:
- IP del client — chi ha effettuato la richiesta
- Timestamp — quando si è verificata
- Riga della richiesta — metodo, percorso, protocollo
- Codice di stato — risposta HTTP (200, 404, 500…)
- Byte inviati — dimensione del corpo della risposta
- Referer — pagina di origine
- User-Agent — stringa del browser o del bot
Esempio di riga da /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"
Su larga scala, questi file arrivano a contenere milioni di righe al giorno. L'obiettivo di questa lezione è estrarre, filtrare e aggregare in modo efficiente i campi utilizzando gli strumenti BASH standard.
Campionamento di un log in tempo reale con tail e grep
Prima di scrivere una pipeline, esamini il log per comprenderne la struttura. tail consente di osservare un flusso in tempo reale; grep lo restringe immediatamente alle righe pertinenti.
Pattern comuni:
tail -n 1000 access.log— ultime 1000 righetail -f access.log— segue il file in tempo realetail -f access.log | grep '" 5'— solo gli errori 5xx man mano che arrivano
L'intuizione fondamentale è che grep esegue la corrispondenza sull'intera riga, quindi è importante delimitare correttamente il pattern. Cercare ' 500 ' (con gli spazi) evita di trovare accidentalmente un percorso URL che contiene la stringa 500.
#!/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] 'Estrazione del codice di stato con cut
cut suddivide ogni riga in base a un delimitatore e stampa i campi selezionati. Nel Combined Log Format il codice di stato si trova al campo 9 quando si suddivide in base agli spazi, ma le virgolette intorno alla riga della richiesta rendono più sicuro contare a partire da un punto di riferimento noto.
Un metodo affidabile consiste nel considerare che la riga della richiesta è sempre racchiusa tra virgolette: il codice di stato è quindi sempre il primo token dopo la virgoletta di chiusura del campo della richiesta. Utilizzando cut -d'"' -f3 si isola tutto ciò che segue la virgoletta della richiesta; un secondo cut -d' ' -f2 seleziona il codice di stato.
Questo cut in due passaggi è un idioma classico per i log CLF: è veloce e non richiede dipendenze esterne.
#!/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 -rnConteggio dei codici di stato con awk
awk è più potente di cut perché può mantenere uno stato tra le righe. Il pattern idiomatico per contare le occorrenze consiste nell'utilizzare un array associativo indicizzato dal valore di interesse.
Nel CLF, il campo $9 (indicizzato a partire da 1 e delimitato dagli spazi) contiene il codice di stato. awk elabora ogni riga, incrementa un contatore e poi stampa un riepilogo ordinato nel blocco END.
Perché preferire awk a cut | sort | uniq -c? Perché awk esegue tutto in un unico passaggio, senza ordinare prima l'intero file — un aspetto fondamentale quando il log ha dimensioni di centinaia di 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 -rnFiltraggio degli errori ed estrazione degli IP dei client
Una delle attività operative più comuni consiste nell'individuare gli IP dei client che generano il maggior numero di errori. Questa operazione combina il filtraggio (solo le righe con errori) con l'estrazione dei campi (l'IP al campo 1).
Strategia della pipeline:
- Utilizzi
awkper filtrare in base all'intervallo del codice di stato ed estrarre l'IP in un unico passaggio — eviti un passaggio separato congrep - Passi il risultato a
sort | uniq -c | sort -rn | headper ottenere rapidamente una vista dei primi N risultati
Questo pattern è sufficientemente veloce da poter essere eseguito su un file di log da 10 GB su un singolo server, senza caricare il file in memoria.
#!/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 -10Analisi della latenza delle risposte nei log dell'applicazione
I server applicativi (Rails, Gunicorn, Express con morgan e altri) registrano spesso la durata delle richieste. Nginx può essere configurato per emettere $request_time come campo aggiuntivo alla fine di ogni riga.
Esempio di formato di log Nginx personalizzato 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';
Una volta registrata la latenza nel log, può utilizzare awk per calcolare media, massimo e approssimazioni dei percentili su milioni di richieste, senza caricare i dati in un 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.logCreazione di un istogramma della latenza con awk
Una singola media nasconde la latenza nella coda della distribuzione. Un istogramma mostra la distribuzione: indica se la maggior parte delle richieste è rapida e alcune sono molto lente (coda lunga), oppure se la distribuzione è uniforme.
Il trucco consiste nel raggruppare ogni valore in un intervallo arrotondato utilizzando l'aritmetica intera all'interno di awk. Moltiplicare per 1000 (convertendo i secondi in millisecondi) e poi utilizzare la divisione intera produce limiti dei gruppi ordinati.
Il risultato è un istogramma testuale leggibile direttamente in un terminale, spesso più rapido dell'invio dei dati a Grafana per un'analisi veloce.
#!/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 -nEstrazione dello User-Agent e rilevamento dei bot
Il campo User-Agent (campo 6 quando si suddivide in base a ") identifica i client. Crawler, scraper e bot dannosi spesso alterano le metriche e aumentano artificialmente il conteggio degli errori. Filtrarli consente di ottenere un'immagine più accurata del traffico degli utenti reali.
Firme comuni dei bot: bot, crawler, spider, curl, python-requests, Googlebot, Bingbot.
Utilizzi grep -iv (inversione senza distinzione tra maiuscole e minuscole) per escludere i bot conosciuti, oppure utilizzi awk per suddividere in base a " e confrontare direttamente il campo UA.
#!/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 -15Aggregazione del traffico per endpoint
Sapere quali endpoint ricevono più traffico — e generano più errori — aiuta a stabilire le priorità per l'ottimizzazione e la pianificazione della capacità. Il percorso della richiesta si trova all'interno del campo della richiesta racchiuso tra virgolette.
Suddivida in base a ", selezioni il campo 2 (la riga della richiesta), quindi estragga il metodo e il protocollo per isolare il percorso. Per le API con parametri nel percorso, come /users/12345, potrebbe anche voler normalizzare gli ID in /users/:id utilizzando sed o un pattern awk più complesso.
#!/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 -20Correlazione degli errori con gli endpoint tramite awk
L'analisi single-pass più potente combina contemporaneamente più campi: endpoint, codice di stato e, facoltativamente, latenza. Gli array associativi di awk indicizzati da valori composti rendono questa operazione semplice e veloce.
Il pattern seguente conta gli errori 5xx per endpoint in un unico passaggio: nessun file temporaneo e nessun ordinamento intermedio fino alla fine. Questo è l'approccio utilizzato negli script di observability in produzione quando servono risposte in meno di un minuto su un log di grandi dimensioni.
#!/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 -20Elaborazione dei log ruotati e compressi
Nella maggior parte dei server i log vengono ruotati ogni giorno. I file più vecchi vengono compressi con gzip come access.log.1.gz, access.log.2.gz e così via. Gli strumenti standard non possono leggerli direttamente, ma due approcci funzionano senza problemi:
zcat— decomprime verso lo standard output e passa il risultato alla pipelinezgrep— esegue grep direttamente nei file gzip senza estrarli
Per analizzare un'intera settimana di log comprendenti file non compressi e compressi, utilizzi la sostituzione di processo oppure concateni i file con zcat. Il frammento seguente elabora gli ultimi 7 file ruotati e il log corrente in tempo reale in un'unica chiamata a awk, senza bisogno di file temporanei.
#!/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 -rnQuale campo di awk contiene il codice di stato HTTP nel Combined Log Format?
Sta scrivendo una one-liner di awk per filtrare solo le risposte HTTP 4xx da un log di accesso Nginx standard in Combined Log Format (delimitato da spazi, con la riga della richiesta tra virgolette). Quale numero di campo identifica correttamente il codice di stato HTTP?
Riepilogo della lezione: pipeline di analisi dei log
In questa lezione ha creato un toolkit completo per analizzare su larga scala i log web e delle applicazioni utilizzando solo le utility BASH standard.
Tecniche principali trattate:
- Prima la struttura — il Combined Log Format ha una disposizione dei campi prevedibile; conoscerla consente di suddividere i dati in modo affidabile con
cut -d'"'o con i riferimenti ai campi diawk. - Estrazione del codice di stato —
awk '{ count[$9]++ }'conta tutti i codici in un'unica passata; utilizzi$9 ~ /^5/per filtrare gli errori del server. - Analisi della latenza — analizzi il campo personalizzato
rt=conawkper calcolare medie, valori massimi e intervalli dell'istogramma senza strumenti esterni. - Analisi di client e bot — suddivida il contenuto in corrispondenza di
"con-F'"'per raggiungere il campo User-Agent; utilizzi una pipe versogrep -ivper escludere i bot prima dell'aggregazione. - Normalizzazione degli endpoint — utilizzi
gsub(/\/[0-9]+/, "/:id")all'interno diawkper accorpare i percorsi parametrizzati prima del conteggio. - Log ruotati — combini
catezcatin una subshell per inviare tutti i file delle rotazioni a un'unica passata della pipeline.
Questi schemi possono essere combinati: può concatenare filtraggio, estrazione, normalizzazione e aggregazione in un'unica pipeline che elabora centinaia di milioni di righe su hardware standard. Padroneggiando queste primitive, raramente avrà bisogno di un servizio dedicato di aggregazione dei log per le analisi ad hoc durante un'indagine su un incidente.
Impara DevOps Bootcamp con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 142
- Lezioni
- 568
Domande Frequenti
La lezione «Analizzare log web e applicativi su larga scala» è gratuita?
Sì — il testo completo di «Analizzare log web e applicativi su larga scala» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso DevOps Bootcamp, passa a CoddyKit PRO. Il corso DevOps Bootcamp include 4 lezioni in totale.
Cosa imparerò in «Analizzare log web e applicativi su larga scala»?
Estragga codici di stato, latenze e campi client dai log di accesso usando grep, cut e awk. Eserciti DevOps Bootcamp con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare DevOps Bootcamp?
Non è richiesta alcuna esperienza precedente. DevOps Bootcamp su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Analizzare log web e applicativi su larga scala»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione DevOps Bootcamp?
Sì. Ogni lezione DevOps Bootcamp include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Analizzare log web e applicativi su larga scala
- Seguire i log in tempo reale e generare avvisi in streaming
- Interrogare journald negli script con journalctl
- Calcolare metriche e istogrammi dai flussi di log