Leggere i log con journalctl
Modulo 6: Servizi e log · Tempo di lettura: 11 minuti
Obiettivo della lezione: Dopo questa lezione saprà cercare in modo mirato nei log del Suo server con journalctl (per servizio, priorità e orario), saprà dove si trovano gli altri file di log ed eviterà che i log riempiano il Suo disco.
Concetti chiave: journald, journal, journalctl -u, -p, --since/--until, -f, -b, -e, -n, priorità (err, warning, info), archiviazione persistente, /var/log/journal, --disk-usage, --vacuum-size, /var/log, logrotate, rsyslog
Il log come primo testimone
Quando qualcosa non funziona sul Suo server, il motivo si trova quasi sempre in un log. Un sito web che mostra una pagina di errore, un servizio che non si avvia, un backup che stanotte non è stato eseguito: il server lo ha annotato. Un buon amministratore guarda prima nel log e solo dopo inizia a modificare le cose.
Sui server Linux moderni journald (parte di systemd) raccoglie i messaggi del kernel, di systemd stesso e di tutti i servizi in un unico registro: il journal. Lo si legge con journalctl.
Per poter leggere tutto deve far parte del gruppo adm o systemd-journal, oppure usare sudo. Senza questi permessi vede solo i Suoi messaggi.
Dove si trova? Persistente o volatile
journald conserva il journal in uno di due posti:
- in
/var/log/journal/: persistente, i log vengono conservati dopo un riavvio; - in
/run/log/journal/: volatile, in memoria, spariscono dopo un riavvio.
L'impostazione predefinita (Storage=auto in /etc/systemd/journald.conf) sceglie la modalità persistente se la cartella /var/log/journal/ esiste. Su Debian il pacchetto systemd crea questa cartella già da Debian 11, e anche su Ubuntu esiste. Lo verifichi:
anna@web1:~$ ls -d /var/log/journal
/var/log/journal
anna@web1:~$ journalctl --list-boots | tail -n 3
-2 3c1f... Sun 2026-11-01 04:30:12 CET Sun 2026-11-08 04:30:01 CET
-1 9ab7... Sun 2026-11-08 04:30:40 CET Mon 2026-11-09 08:12:05 CET
0 e41d... Mon 2026-11-09 08:12:30 CET Mon 2026-11-09 11:40:17 CETSe vede un solo avvio mentre il server è già stato riavviato in passato, i Suoi log sono volatili. Crei la cartella (sudo mkdir -p /var/log/journal e sudo systemd-tmpfiles --create --prefix /var/log/journal) e riavvii journald. È importante: dopo un crash vorrà proprio sapere che cosa è successo prima del riavvio.
Da Debian 12, Debian non installa più rsyslog per impostazione predefinita. Quel programma un tempo scriveva file di testo come /var/log/syslog e /var/log/auth.log. Su un nuovo server Debian quindi questi file non esistono; tutto si trova nel journal. Ubuntu invece ha ancora rsyslog. Le guide che dicono "guardi in /var/log/auth.log" su Debian si traducono in journalctl -u ssh.
Cercare: i filtri che userà davvero
Senza filtri journalctl mostra tutto, a partire dal messaggio più vecchio. Raramente è ciò che desidera. I filtri principali, che si possono combinare:
| Filtro | Esempio | Che cosa |
|---|---|---|
-u <unit> | journalctl -u nginx | solo quel servizio |
-p <prioriteit> | journalctl -p err | solo errori e livelli più gravi |
--since, --until | --since "2026-11-09 03:00" --until "04:00" | intervallo di tempo; anche today, yesterday, "1 hour ago" |
-b | journalctl -b, journalctl -b -1 | dall'avvio attuale, o da quello precedente |
-f | journalctl -u nginx -f | seguire in tempo reale (come tail -f), interrompere con Ctrl+C |
-e | journalctl -u ssh -e | saltare alla fine |
-n | journalctl -u ssh -n 50 | le ultime 50 righe |
-k | journalctl -k | solo i messaggi del kernel |
--no-pager | senza paginazione, utile con grep |
Le priorità vanno da 0 (emerg) a 7 (debug): emerg, alert, crit, err, warning, notice, info, debug. Con -p err ottiene err e tutto ciò che è più grave. -p warning mostra anche gli avvisi.
Un tipico percorso di ricerca. Da stamattina il Suo sito web restituisce un errore 502:
anna@web1:~$ systemctl status php8.4-fpm
× php8.4-fpm.service - The PHP 8.4 FastCGI Process Manager
Active: failed (Result: exit-code) since Mon 2026-11-09 07:02:11 CET; 4h ago
...
anna@web1:~$ sudo journalctl -u php8.4-fpm --since today -p warning --no-pager
nov 09 07:02:10 web1 php-fpm8.4[1830]: [09-Nov-2026 07:02:10] ERROR: [/etc/php/8.4/fpm/pool.d/www.conf:42] unknown entry 'pm.max_children '
nov 09 07:02:10 web1 php-fpm8.4[1830]: [09-Nov-2026 07:02:10] ERROR: FPM initialization failed
nov 09 07:02:11 web1 systemd[1]: php8.4-fpm.service: Main process exited, code=exited, status=78/CONFIG
nov 09 07:02:11 web1 systemd[1]: php8.4-fpm.service: Failed with result 'exit-code'.La causa è scritta lì in chiaro: un errore di battitura alla riga 42 di un file di configurazione. Lo stato 78 (CONFIG) conferma che si tratta di un errore di configurazione. Non deve tirare a indovinare.
Due consigli per la lettura:
- Legga dall'alto verso il basso e cerchi il primo errore. Un errore provoca spesso un'intera serie di messaggi conseguenti. Il primo è di solito la causa.
- Faccia attenzione all'orario. Che cosa è cambiato in quel momento? Un aggiornamento automatico (lezione 4.2:
/var/log/unattended-upgrades/), una Sua modifica, un riavvio?
Altri file di log
Non tutto si trova nel journal. Molti programmi scrivono anche (o soltanto) propri file in /var/log/:
| File o cartella | Che cosa |
|---|---|
/var/log/nginx/access.log e error.log | ogni richiesta e ogni errore di nginx |
/var/log/apt/history.log | che cosa ha installato apt e quando |
/var/log/unattended-upgrades/ | aggiornamenti automatici (lezione 4.2) |
/var/log/fail2ban.log | blocchi (lezione 5.3) |
/var/log/mysql/ o il journal | MariaDB/MySQL, a seconda della configurazione |
I file di testo di grandi dimensioni si leggono con less (ricerca con /), la fine con tail -n 50, in tempo reale con tail -f e si filtrano con grep:
anna@web1:~$ sudo grep " 502 " /var/log/nginx/access.log | tail -n 5I log dei container Docker non si trovano in /var/log ma in Docker stesso: docker compose logs (lezione 9.3).
I log non devono riempire il disco
Un disco pieno è una delle cause più frequenti di un server che "all'improvviso" smette di funzionare: i database si fermano, gli aggiornamenti falliscono, a volte non è nemmeno più possibile accedere. Spesso i colpevoli sono i log.
Il journal si limita da solo. Per impostazione predefinita usa al massimo il 10% del file system, fino a un massimo di 4 GB (SystemMaxUse=). Quanto spazio usa ora e come fare pulizia:
anna@web1:~$ journalctl --disk-usage
Archived and active journals take up 512.0M in the file system.
anna@web1:~$ sudo journalctl --vacuum-time=30d # rimuovere i file più vecchi di 30 giorni
anna@web1:~$ sudo journalctl --vacuum-size=500M # fino a 500 MBSe desidera un limite fisso, lo imposti in un drop-in /etc/systemd/journald.conf.d/grootte.conf:
[Journal]
SystemMaxUse=1Ge riavvii journald con sudo systemctl restart systemd-journald.
I file di testo in /var/log sono gestiti da logrotate: ogni giorno o settimana un file viene rinominato (error.log.1), le versioni più vecchie vengono compresse (.gz) e la più vecchia viene eliminata. Le regole per ciascun programma si trovano in /etc/logrotate.d/. I pacchetti della distribuzione portano con sé la propria regola. Se un Suo programma o script scrive in un proprio file di log, crei Lei stesso una regola, altrimenti il file cresce all'infinito.
Cercare che cosa occupa spazio:
anna@web1:~$ df -h /
anna@web1:~$ sudo du -xh /var/log | sort -h | tail -n 5Log e privacy
I log contengono indirizzi IP, nomi utente e a volte indirizzi email: si tratta di dati personali. Non li conservi più a lungo del necessario (da qualche settimana a qualche mese è prassi comune per un piccolo server), non li lasci accessibili pubblicamente (una cartella /logs nella webroot è un errore noto) e non li copi alla leggera su servizi di terzi.
Su AlmaLinux e Rocky Linux
journalctl funziona allo stesso modo. Lì rsyslog è ancora attivo per impostazione predefinita, con file come /var/log/messages e /var/log/secure (l'equivalente di auth.log). I messaggi di SELinux si trovano in /var/log/audit/audit.log; ausearch -m avc -ts recent mostra i rifiuti recenti.
Riepilogo
- journald raccoglie tutti i messaggi nel journal; lo legga con
journalctl, filtrando per servizio (-u), priorità (-p), orario (--since) e avvio (-b). - Verifichi che il journal sia persistente (
/var/log/journalesiste), altrimenti perde i Suoi log dopo un riavvio. - Debian 12 e versioni successive non hanno rsyslog per impostazione predefinita e quindi nemmeno
/var/log/auth.loge/var/log/syslog; tutto si trova nel journal. - Cerchi il primo errore e guardi che cosa è cambiato in quel momento.
- Tenga d'occhio le dimensioni: il journal si limita da solo (
--disk-usage,--vacuum-*), i file di testo sono gestiti da logrotate.
Quiz
Esercizio
Esercizio Z6.2: Analizzare un servizio che va in crash. Il file di esempio journal-crash-1.txt contiene l'output di systemctl status e journalctl di un servizio che si riavvia continuamente e poi si arrende. Risponda: come si chiama il servizio, quante volte systemd ha tentato di avviarlo, con quale codice di uscita si è fermato, qual è la causa secondo il primo messaggio di errore e a che ora systemd ha rinunciato? Il programma confronta le risposte con la chiave prestabilita. Poi verifichi sul Suo server se journalctl -p err -b mostra errori e se il Suo journal è persistente.
Per approfondire
- Manuale
journalctl(1): https://manpages.debian.org/trixie/systemd/journalctl.1.en.html - Manuale
journald.conf(5)(Storage=, SystemMaxUse=): https://manpages.debian.org/trixie/systemd/journald.conf.5.en.html - Debian 12, note di rilascio 5.1.7 (rsyslog non più predefinito): https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html
