Post Image

I logger in Python sono strumenti essenziali per monitorare e registrare eventi durante l'esecuzione di un programma. Sono utilizzati per tenere traccia delle attività, rilevare errori, e diagnosticare problemi. In questo articolo, esploreremo come istanziare e utilizzare i logger in Python, spiegando le basi della libreria logging, la configurazione di più logger e l'importanza della loro corretta implementazione.

A cosa servono i logger?

I logger servono a registrare messaggi che possono essere utilizzati per diverse finalità:

  • Debugging: Per identificare e risolvere bug nel codice.
  • Monitoraggio: Per tenere traccia delle operazioni e delle prestazioni di un'applicazione.
  • Audit: Per avere un registro delle operazioni eseguite, utile per analisi.
  • Notifiche: Per informare gli sviluppatori o gli amministratori di sistema su eventi critici.

Istanziare un logger

La libreria logging di Python consente di creare e configurare i logger in modo molto semplice. Il seguente codice mostra un esempio di base.

import logging

# Creazione di un logger di nome mio_logger
logger = logging.getLogger('mio_logger')

# Impostazione del livello di log
logger.setLevel(logging.DEBUG)

# Creazione di un handler che scrive su console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# Creazione di un formato per i log
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
console_handler.setFormatter(formatter)

# Aggiunta dell'handler al logger
logger.addHandler(console_handler)

# Scrittura di messaggi di log
logger.debug('Questo è un messaggio di debug')
logger.info('Questo è un messaggio informativo')
logger.warning('Questo è un avvertimento')
logger.error('Questo è un errore')
logger.critical('Questo è un messaggio critico')

Istanziare più logger

Alcune volte, potrebbe essere necessario ed utile avere più di un logger, ognuno con configurazioni differenti. Ad esempio, potresti volere un logger per registrare i messaggi di debug e un altro per gli errori critici. Di seguito ti mostro un esempio di codice Python.

import logging

# Logger per il debug
debug_logger = logging.getLogger('debug_logger')
debug_logger.setLevel(logging.DEBUG)
debug_handler = logging.StreamHandler()
debug_handler.setLevel(logging.DEBUG)
debug_handler.setFormatter(
    logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
)
debug_logger.addHandler(debug_handler)

# Logger per gli errori
error_logger = logging.getLogger('error_logger')
error_logger.setLevel(logging.ERROR)
error_handler = logging.StreamHandler()
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(
    logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
)
error_logger.addHandler(error_handler)

# Utilizzo dei logger
debug_logger.debug('Questo è un messaggio di debug')
error_logger.error('Questo è un messaggio di errore')

Il precedente esempio mostra chiaramente la possibilità di creare diversi logger per soddisfare le tue esigenze. Potresti istanziare un logger per registrare anche solo un'operazione specifica o per un controllo audit interno istanziare un altro logger. La libreria logging di Python, ci offre la massima libertà nella creazione dei nostri logger.

Configurazioni avanzate: configurazione tramite file

Gli esempi precedenti hanno mostrato come istanziare i logger all'interno di un file Python. Tuttavia le istanze dei logger sono state creare e configurate all'interno del file Python. L'attività di configurazione dei logger può essere anche gestita al di fuori dei file Python, inserendola in opportuni file di configurazione in formato json, yaml, ini. Vediamo un esempio di configurazione ed utilizzo di un file ini.

[loggers]
keys=root,iniErrorLogger,iniDebugLogger

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=CRITICAL
handlers=consoleHandler

[logger_iniErrorLogger]
level=ERROR
handlers=consoleHandler
qualname=iniErrorLogger
propagate=0

[logger_iniDebugLogger]
level=DEBUG
handlers=consoleHandler
qualname=iniDebugLogger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

Nel precedente esempio, possono essere instanziati iniErrorLogger, iniDebugLogger ed il logger di root (obbligatorio in tale configurazione). Ti mostro un esempio di codice Python:

Configurazioni avanzate: logger gerarchici

I logger in Python supportano una struttura gerarchica; in questo tipo di struttura, i logger figli ereditano le proprietà dei logger padri e possono aggiungere proprietà o sovrascriverle. Questa caratteristica è molto utile per organizzare i logger in base ai componenti applicativi.

import logging

# Logger genitore
logger_genitore = logging.getLogger('genitore')
logger_genitore.setLevel(logging.DEBUG)

# Logger figlio
logger_figlio = logging.getLogger('genitore.figlio')
logger_figlio.setLevel(logging.INFO)

# Handler e formatter
handler = logging.StreamHandler()
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

logger_genitore.addHandler(handler)
logger_figlio.addHandler(handler)

# Messaggi di log
logger_genitore.debug('Messaggio di debug dal logger genitore')

logger_figlio.info('Messaggio informativo dal logger figlio')
logger_figlio.error('Errore dal logger figlio')

Molto importante ricordare che i messagi dei logger figlio sono, per default, propagati al logger genitore. Se desideri interrompere la propagazione devi inserire:

logger_figlio.propagate = 0

Conclusioni

I logger sono uno strumento potente per il monitoraggio e la gestione delle applicazioni in Python. Con una corretta configurazione, possono aiutarti a identificare problemi, monitorare l'andamento dell'applicazione e mantenere un registro delle operazioni importanti. Implementare e utilizzare i logger in modo efficace è una competenza fondamentale per qualsiasi sviluppatore Python.

Questo articolo ha fornito una panoramica su come istanziare e configurare i logger in Python, nonché su come gestire più logger per diverse esigenze. Sperimenta con la libreria logging per adattarla al meglio alle tue necessità specifiche.