grep sui log: il filtro, non il lettore
Quando devi capire cosa sta succedendo in un sistema Linux, grep non serve a “aprire” un log: serve a ridurre il rumore. La differenza è pratica. Un file da 200 MB letto con cat o in un editor ti mostra tutto; grep ti porta direttamente alle righe che contano, spesso con il contesto giusto attorno.
Se l’obiettivo è trovare errori PHP, eventi di systemd, timeout di nginx o messaggi del kernel, il comando corretto non è quasi mai uno solo. Di solito combini grep con tail, journalctl, zgrep, awk o less. Il punto è costruire una lettura rapida e ripetibile, non “sfogliare” il log.
La regola mentale è semplice: prima delimiti il problema, poi filtri il contenuto. Se non sai cosa stai cercando, grep ti aiuta meno. Se hai già un indizio — un codice HTTP, un PID, un nome servizio, una stringa di errore, una data — diventa lo strumento più veloce che hai.
Il caso d’uso corretto: partire da un indizio
Su un server reale non cerchi “tutti i log”. Cerchi una firma: ERROR, segfault, timeout, permission denied, un hostname, un IP, un endpoint, un job ID.
Esempi tipici:
- Apache/Nginx: filtrare per
500,upstream timed out,client denied by server configuration - PHP-FPM:
Primary script unknown,child exited on signal 11,pool - systemd:
failed,started,stopped, nome del servizio - Kernel:
oom-killer,nvme,ext4 error,segfault
Con un indizio solido, grep diventa una lente. Senza indizio, rischia di diventare rumore filtrato male.
La forma base: cercare una stringa nei log
La sintassi più semplice è questa:
grep 'errore' /var/log/syslogQui grep stampa tutte le righe che contengono la stringa errore. Se il file è grande, il guadagno è immediato: niente scroll inutile, niente ricerca manuale.
Alcuni punti da non dimenticare:
- Le virgolette evitano problemi con spazi o caratteri speciali.
grepdistingue maiuscole e minuscole per default.- Se il pattern è una regex, il comportamento cambia: non stai cercando solo testo letterale.
Per esempio, se vuoi cercare una parola esatta senza interpretazione regex, usa grep -F:
grep -F '500 Internal Server Error' /var/log/nginx/error.logQuesto è utile quando il messaggio è lungo e non vuoi che caratteri come ., *, [ o ] vengano interpretati.
Contesto: vedere cosa succede prima e dopo la riga
Una riga isolata spesso non basta. Nei log il valore sta nel contesto: cosa è successo subito prima e subito dopo.
Le opzioni più usate sono:
-Aper le righe successive-Bper le righe precedenti-Cper entrambe
Esempio:
grep -C 3 'upstream timed out' /var/log/nginx/error.logQuesto mostra tre righe prima e tre dopo ogni match. È una delle combinazioni più utili quando devi capire se il timeout è isolato o parte di una sequenza più ampia.
Se stai inseguendo un errore applicativo, il contesto aiuta anche a collegare eventi diversi: request ID, user ID, endpoint, stack trace, query SQL. In pratica, -C riduce il tempo perso a ricostruire la cronologia a mano.
Maiuscole, minuscole e log sporchi
Nei log reali la forma del messaggio cambia. A volte il software scrive error, a volte ERROR, a volte Error. Se non hai controllo sul formato, usa la ricerca case-insensitive:
grep -i 'error' /var/log/messagesQuesto evita falsi negativi banali. È una scelta quasi sempre sensata quando fai troubleshooting iniziale.
Se però il log è molto rumoroso e vuoi precisione, conviene tornare a una ricerca più stretta. In pratica:
-iper esplorare- senza
-iquando sai già esattamente come è scritto il messaggio
Un altro caso classico è il filtro su parole che compaiono dentro altre parole. Se cerchi fail, potresti trovare anche failed, failure, failover. Se vuoi solo la parola intera, usa -w:
grep -w 'fail' /var/log/auth.logInvertire il filtro: trovare ciò che non vuoi
Molto spesso il valore di grep non è trovare una riga, ma escludere il rumore. L’opzione -v stampa tutto quello che non corrisponde al pattern.
grep -v 'healthcheck' /var/log/nginx/access.logQuesto è utile quando i log sono pieni di richieste automatiche, ping, monitoraggi o probe di bilanciatori. Se stai cercando solo traffico utente reale, l’inversione ti ripulisce l’output.
Attenzione però: -v va usato con criterio. Più eccezioni accumuli, più il filtro diventa fragile. Se ti accorgi di stare escludendo dieci pattern diversi, probabilmente conviene cambiare approccio e filtrare a monte con un parser o con una query più strutturata.
Colori, numeri di riga e output leggibile
Quando lavori al terminale, la leggibilità conta. grep può evidenziare i match con il colore:
grep --color=auto 'error' /var/log/syslogDi solito il colore è già attivo in molte shell, ma non sempre. Se vuoi renderlo esplicito, questa opzione aiuta.
Se devi poi andare a verificare il file in un editor o con less, i numeri di riga sono utili:
grep -n 'PHP Fatal error' /var/log/php8.2-fpm.logIl numero di riga non ti serve solo per estetica. Ti permette di aprire il file nel punto giusto e di confrontare più facilmente la sequenza degli eventi.
In alcuni casi è utile anche vedere il nome del file, soprattutto se stai cercando su più log in una volta sola. grep lo mostra automaticamente quando l’input arriva da più file.
Cercare in più file e in directory intere
Una delle situazioni più comuni è avere log distribuiti in più file: rotazioni giornaliere, servizi diversi, istanze diverse. In quel caso puoi passare più file insieme:
grep -n 'timeout' /var/log/nginx/error.log /var/log/nginx/error.log.1Se vuoi cercare in una directory, grep da solo non scende ricorsivamente; puoi combinare con find oppure usare grep -r:
grep -r 'OOM' /var/log/Questa opzione è comoda, ma va usata con attenzione in directory molto grandi. Se la struttura contiene tanti file inutili, rischi output enorme e tempi lunghi. In questi casi è meglio restringere il perimetro con find:
find /var/log -type f -name '*.log' -exec grep -Hn 'timeout' {} +Il vantaggio è che controlli meglio quali file stai leggendo. Il difetto è che il comando è più lungo. In troubleshooting serio, però, la precisione vale più della sintesi.
Log compressi: quando serve zgrep
Le rotazioni sono normali. Molti log finiscono in file compressi con estensione .gz. Qui grep da solo non basta; entra in gioco zgrep.
zgrep 'failed' /var/log/auth.log.1.gzLa logica è la stessa: cerca il pattern dentro un file compresso senza decomprimerlo manualmente. È molto più comodo quando devi controllare un evento di ieri o di due giorni fa.
Se hai bisogno di fare analisi più serie su archivi compressi, puoi combinare zgrep con -n, -i e -C come faresti con grep. Il comportamento è simile, quindi la curva di apprendimento è bassa.
Regex utile, ma senza esagerare
grep supporta espressioni regolari. È comodo, ma anche il punto in cui molti si complicano la vita. Nei log, spesso basta poco:
^per inizio riga$per fine riga.come carattere qualsiasi*per ripetizioni
Esempio:
grep '^2026-04-08' /var/log/app.logQuesto filtra tutte le righe di una certa data, utile quando i log sono in formato testuale con timestamp all’inizio.
Se vuoi cercare un pattern più strutturato, ad esempio un codice HTTP 5xx, puoi usare qualcosa del genere:
grep ' 5[0-9][0-9] ' /var/log/nginx/access.logQui stai cercando le righe con status code compreso tra 500 e 599, separato da spazi. È un trucco semplice ma efficace per isolare gli errori server-side.
Se il pattern diventa troppo articolato, fermati un attimo. A quel punto forse grep non è il miglior strumento da solo. Potresti aver bisogno di awk, sed, jq o di un sistema di logging strutturato.
Pipeline pratiche: grep insieme ad altri comandi
Nella vita vera grep lavora quasi sempre in pipeline. Alcuni esempi utili:
journalctl -u nginx --since '1 hour ago' | grep -i 'timeout'Qui parti dal journal di systemd e filtri solo i messaggi che contengono timeout. È una combinazione molto più veloce che scorrere tutto il servizio a mano.
tail -f /var/log/php8.2-fpm.log | grep --line-buffered 'error'Con --line-buffered il filtro resta reattivo anche in tempo reale. Questo è utile durante un deploy o mentre stai osservando un problema intermittente.
grep 'ERROR' app.log | awk '{print $1, $2, $NF}'Qui grep isola le righe critiche e awk estrae i campi che ti interessano. È un approccio molto pratico quando devi costruire una mini-analisi al volo.
Un esempio reale: capire perché il sito risponde 500
Supponiamo che un sito restituisca 500 dopo un aggiornamento. Il primo istinto non dovrebbe essere toccare la configurazione, ma leggere i log giusti. Una sequenza sensata è questa:
- Controlli il web server:
grep -i 'error\|fail\|timeout' /var/log/nginx/error.log - Controlli PHP-FPM:
grep -i 'fatal\|warning\|pool' /var/log/php8.2-fpm.log - Controlli il journal del servizio:
journalctl -u php8.2-fpm --since '30 min ago' | grep -i 'error'
Spesso la risposta è già lì: permessi errati su un file, socket non raggiungibile, memory limit, script mancante, upstream in timeout. grep ti aiuta a passare da “sito giù” a una pista concreta in pochi minuti.
Se il log è verboso, aggiungi contesto:
grep -C 5 -i 'fatal' /var/log/php8.2-fpm.logIn un caso del genere, vedere cinque righe prima e dopo può mostrarti la request, il file coinvolto e l’errore reale, non solo il sintomo.
Errori comuni nell’uso di grep sui log
Ci sono errori ricorrenti che fanno perdere tempo:
- Usare
grepsenza sapere cosa cercare, sperando che “salti fuori qualcosa”. - Dimenticare
-ie perdere match solo per differenza di maiuscole. - Ignorare il contesto e leggere una riga fuori sequenza.
- Usare regex troppo complesse quando basta una ricerca letterale con
-F. - Filtrare file compressi con
grepinvece dizgrep.
Un altro problema classico è confondere il log giusto con il log più comodo. Se il guasto è a livello di reverse proxy, il log dell’app non ti dirà tutto. Se il problema è nel database, il web server vedrà solo il sintomo. grep funziona bene quando sai quale layer stai osservando.
Quando grep non basta più
grep è perfetto per il primo taglio, ma non è un parser completo. Quando i log sono JSON, quando devi correlare eventi tra servizi diversi o quando ti servono metriche aggregate, conviene cambiare strumento.
Se il log è strutturato in JSON, puoi comunque filtrare con grep per un primo colpo d’occhio:
grep '
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.