HOWTO · Python
Accesso allo stdout in Python
Possiamo usare le funzioni logging.basicConfig() e logging.StreamHandler() per accedere a stdout in Python.
In questa pagina
Per inviare i messaggi di log di Python all’output standard (stdout), configura logging.basicConfig() con stream=sys.stdout. Per un controllo maggiore, collega un logging.StreamHandler(sys.stdout) a un logger. Se gli stessi record devono comparire sia nella console sia in un file, affianca al gestore di flusso un FileHandler separato.
Scrivere i log su stdout con la funzione logging.basicConfig() in Python
Per configurare in modo semplice l’intera applicazione, logging.basicConfig() imposta il logger radice. Il parametro stream seleziona il flusso di output; per impostazione predefinita, il logging usa sys.stderr. Impostalo su sys.stdout per inviare i record all’output standard. level determina quali record superano il logger radice, mentre format definisce il formato di ogni riga emessa.
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s: %(message)s",
stream=sys.stdout,
)
logging.info("Application started")
INFO: Application started
basicConfig() è una comoda configurazione da usare una sola volta per il logger radice. Se un’altra parte dell’applicazione ha già aggiunto un gestore al logger radice, una chiamata successiva lascia invariata quella configurazione: modificare stream in questa chiamata non reindirizza quindi l’output. Dalla versione 3.8 di Python, force=True rimuove i gestori radice esistenti prima di applicare la nuova configurazione. Usalo solo se il tuo codice deve sostituire la configurazione di logging dell’applicazione; altrimenti, configura il logging una sola volta nel punto di ingresso dell’applicazione.
Le opzioni filename e filemode configurano l’output su file: filename specifica il nome del file, mentre filemode stabilisce come aprirlo e, per impostazione predefinita, usa la modalità di aggiunta ("a"). Non passare insieme filename e stream a basicConfig(); scegli una sola destinazione per questa configurazione. Per inviare i record sia all’output standard sia a un file, usa gestori separati, come mostrato più avanti. Inoltre, basicConfig() configura il logger radice solo se non ha già gestori, a meno che non si usi force=True (disponibile da Python 3.8).
Scrivere i log su stdout con la funzione logging.StreamHandler() in Python
Usa un gestore esplicito quando vuoi controllare un logger con nome o combinare più destinazioni. Per impostazione predefinita, logging.StreamHandler() scrive su sys.stderr, quindi passa esplicitamente sys.stdout. Sia il livello del logger sia quello del gestore influiscono sui record emessi: un record deve superare entrambi. Questo esempio crea un gestore per stdout e uno per un file, quindi li collega allo stesso logger.
import logging
import sys
import tempfile
from pathlib import Path
log_path = Path(tempfile.gettempdir()) / "python-logging-example.log"
logger = logging.getLogger("example")
logger.setLevel(logging.INFO)
logger.propagate = False
formatter = logging.Formatter("%(levelname)s: %(message)s")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(formatter)
file_handler = logging.FileHandler(log_path, mode="w", encoding="utf-8")
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
logger.addHandler(file_handler)
logger.info("Application started")
for handler in (stdout_handler, file_handler):
handler.close()
logger.removeHandler(handler)
INFO: Application started
Ogni gestore formatta il record e lo scrive nella propria destinazione. Il file viene creato nella directory temporanea del sistema e mode="w" sostituisce il file dell’esempio a ogni esecuzione. In un’applicazione di lunga durata, configura i gestori una sola volta invece di aggiungerli ripetutamente: i gestori duplicati possono far comparire più volte lo stesso record. In produzione, gestisci il percorso del file e il ciclo di vita dei gestori in base alle esigenze dell’applicazione.
Conclusione
Usa logging.basicConfig() con stream=sys.stdout per configurare rapidamente il logger radice. Scegli logging.StreamHandler(sys.stdout) quando ti serve controllare un logger con nome, personalizzare le impostazioni del gestore o usare più destinazioni. Un StreamHandler senza un flusso esplicito scrive su stderr; per inviare i log sia alla console sia a un file servono gestori separati per il flusso e per il file.