Salta al contenuto principale

Orvieto Linux User Group | Promozione software libero a Orvieto

Leggere e analizzare i log Linux con Python

Quando un programma smette di funzionare, un servizio restituisce un errore o un server comincia a comportarsi in modo insolito, una delle prime cose da controllare sono i log. Questi registri raccolgono informazioni su ciò che accade durante l’esecuzione di applicazioni e servizi e possono aiutarci a ricostruire l’origine di un problema.

Linux mette già a disposizione strumenti molto efficaci per consultare queste informazioni. Ma cosa succede quando i messaggi sono migliaia e vogliamo individuare automaticamente quelli più importanti?

È qui che Python può diventare un valido alleato. Con poche righe di codice possiamo cercare parole chiave, contare gli errori e generare un riepilogo leggibile, senza dover esaminare manualmente ogni singola riga.

In questa guida costruiremo un piccolo analizzatore di log, adatto anche a chi sta iniziando a utilizzare Python su Linux.

Prima di tutto, che cosa sono i log?

Un log è un registro di eventi prodotto dal sistema operativo, da un servizio o da un’applicazione. Può contenere informazioni sulle operazioni eseguite, avvisi, errori e dettagli utili per capire come si è comportato un programma.

Su molte distribuzioni Linux moderne, basate su systemd, possiamo consultare i messaggi del sistema con journalctl. Per esempio:

journalctl -p warning --since today

Questo comando mostra i messaggi con priorità di avviso o più elevata, a partire dall’inizio della giornata. È un primo modo per restringere la ricerca quando sospettiamo che qualcosa non stia funzionando correttamente.

Se vogliamo approfondire la consultazione dei log e i filtri disponibili, possiamo fare riferimento alla nostra guida dedicata a journalctl.

Python entra in gioco quando vogliamo automatizzare un’analisi ripetitiva, elaborare file di log prodotti da applicazioni differenti oppure creare un rapporto da consultare senza leggere ogni messaggio.

Prepariamo un piccolo file di log

Per imparare senza modificare file di sistema, lavoriamo inizialmente su un file di prova. Creiamo una directory dedicata:

mkdir -p ~/laboratorio-log
cd ~/laboratorio-log

Apriamo quindi un editor di testo e creiamo un file chiamato app.log con questo contenuto:

2026-11-10 08:10:12 INFO Avvio applicazione
2026-11-10 08:10:15 WARNING Memoria disponibile in diminuzione
2026-11-10 08:10:20 ERROR Connessione al database fallita
2026-11-10 08:10:25 INFO Nuovo tentativo di connessione
2026-11-10 08:10:27 ERROR Connessione al database fallita
2026-11-10 08:10:30 CRITICAL Servizio non disponibile
2026-11-10 08:10:35 INFO Applicazione arrestata

Si tratta di messaggi inventati a scopo didattico, ma la struttura è simile a quella utilizzata da molte applicazioni: data, ora, livello del messaggio e descrizione dell’evento.

Nel nostro esempio sono presenti messaggi informativi (INFO), avvisi (WARNING), errori (ERROR) e un evento critico (CRITICAL). Il nostro obiettivo è trovare rapidamente quelli che meritano attenzione e capire quante volte si sono verificati.

Scriviamo il nostro analizzatore in Python

Creiamo un file chiamato analizza_log.py nella stessa directory. Lo script leggerà il file indicato sulla riga di comando, riconoscerà i livelli di gravità e produrrà un riepilogo.

#!/usr/bin/env python3

from collections import Counter
from pathlib import Path
import sys

if len(sys.argv) != 2:
    print(f"Uso: {sys.argv[0]} file.log")
    sys.exit(1)

percorso = Path(sys.argv[1])

if not percorso.is_file():
    print(f"Errore: il file '{percorso}' non esiste.")
    sys.exit(1)

livelli = ("CRITICAL", "ERROR", "WARNING", "INFO")
conteggi = Counter()
righe_problematiche = []

with percorso.open("r", encoding="utf-8", errors="replace") as file:
    for numero, riga in enumerate(file, start=1):
        testo = riga.strip()

        if not testo:
            continue

        trovato = False

        for livello in livelli:
            if livello in testo.upper():
                conteggi[livello] += 1

                if livello in ("CRITICAL", "ERROR"):
                    righe_problematiche.append(
                        (numero, testo)
                    )

                trovato = True
                break

        if not trovato:
            conteggi["ALTRO"] += 1

print(f"\nAnalisi del file: {percorso}")
print(f"Righe problematiche: {len(righe_problematiche)}")

print("\nRiepilogo per livello:")
for livello in (*livelli, "ALTRO"):
    print(f"{livello:10} {conteggi[livello]}")

if righe_problematiche:
    print("\nErrori e messaggi critici:")
    for numero, testo in righe_problematiche:
        print(f"Riga {numero}: {testo}")

Non è necessario conoscere ogni istruzione prima di provare lo script. Vediamo però gli elementi principali, perché comprendere il funzionamento ci permetterà di adattarlo in futuro.

Il modulo pathlib ci aiuta a gestire il percorso del file e a verificare che esista. Counter, invece, permette di contare facilmente quante volte compare ciascun livello. Il programma legge il file una riga alla volta, cerca le parole chiave e conserva i messaggi classificati come ERROR o CRITICAL, insieme al numero della riga originale.

Abbiamo previsto anche alcuni controlli: se non indichiamo il file da analizzare, oppure se il percorso non esiste, il programma mostra un messaggio esplicativo anziché interrompersi con un errore poco comprensibile.

È importante ricordare che questo è un analizzatore didattico: cerca parole chiave nel testo e non interpreta uno standard universale dei log. Se un’applicazione utilizza formati diversi, sarà necessario adattare i criteri di riconoscimento.

Eseguiamo lo script e leggiamo il risultato

Dal terminale, nella directory in cui abbiamo salvato i due file, lanciamo:

python3 analizza_log.py app.log

Nel nostro esempio, il riepilogo indicherà due messaggi ERROR, un messaggio CRITICAL e un messaggio WARNING. Verranno inoltre mostrati i numeri di riga e il testo completo dei messaggi più importanti.

Queste informazioni possono sembrare semplici, ma diventano preziose quando un file contiene centinaia o migliaia di eventi. Invece di cercare manualmente ogni occorrenza, possiamo ottenere una prima panoramica in pochi istanti.

Possiamo anche rendere lo script eseguibile:

chmod +x analizza_log.py
./analizza_log.py app.log

Il risultato sarà lo stesso. In alternativa, possiamo continuare a usare python3 senza modificare i permessi del file.

Come passare dai log di prova a quelli reali

Una volta compreso il meccanismo, possiamo utilizzare lo script su un file di log di un’applicazione, purché abbiamo il diritto di leggerlo e il suo formato sia compatibile con i criteri che abbiamo scelto.

Su Linux, alcuni log possono essere accessibili soltanto a utenti o gruppi specifici. Se riceviamo un errore di permessi, non è una buona idea rendere leggibili a tutti i file di sistema. È preferibile verificare le autorizzazioni e utilizzare un account autorizzato.

Possiamo anche esportare una porzione del journal in un file di testo e analizzarla successivamente. Per esempio:

journalctl --since today --no-pager > log-giornata.txt

Il comando crea una copia dei messaggi disponibili per la giornata corrente. Lo script potrà poi analizzare quel file:

python3 analizza_log.py log-giornata.txt

L’esportazione può contenere informazioni sensibili, come nomi utente, indirizzi IP o dettagli delle applicazioni. Prima di condividere il file o conservarlo in un luogo accessibile ad altri, è quindi opportuno controllarne il contenuto. Inoltre, l’analizzatore riconosce soltanto i livelli che abbiamo definito: non tutti i messaggi del journal utilizzano necessariamente le stesse etichette del nostro esempio.

Un primo passo verso l’automazione

Questo piccolo programma può essere esteso in molte direzioni. Potremmo salvare il riepilogo in un file, analizzare più registri, cercare una particolare parola chiave oppure confrontare il numero di errori tra due periodi.

In un ambiente amministrato regolarmente, lo script potrebbe diventare parte di una procedura di manutenzione. Prima di pianificare esecuzioni automatiche, tuttavia, conviene verificarne il comportamento sui file reali e decidere come gestire gli errori, i permessi e la conservazione dei risultati.

Python non sostituisce gli strumenti nativi di Linux: li completa. journalctl resta molto efficace per consultare il journal e filtrare gli eventi; Python permette invece di costruire analisi personalizzate e ripetibili.

È proprio questa combinazione a rendere l’automazione interessante: partiamo da uno strumento semplice, comprendiamo i dati che abbiamo a disposizione e aggiungiamo codice soltanto quando ci permette di risparmiare tempo o ottenere informazioni più utili.

Il nostro primo analizzatore è volutamente essenziale, ma rappresenta già una base concreta per affrontare attività più avanzate di monitoraggio e amministrazione Linux.

LICENZA E CONDIZIONI D’USO

Questo How-to è rilasciato sotto licenza Creative Commons Attribution-NonCommercial 3.0 Italy. 

CONTATTI DELL’AUTORE

Marco Ciammella marco@orvietolinux.it

Orvieto Linux User Group info@orvietolinux.it