HOWTO · Python
Log para stdout em Python
Podemos usar as funções logging.basicConfig() e logging.StreamHandler() para registrar no stdout em Python.
Nesta página
Para enviar mensagens de log do Python à saída padrão (stdout), configure logging.basicConfig() com stream=sys.stdout. Para ter mais controle, adicione um logging.StreamHandler(sys.stdout) a um logger. Use um FileHandler separado junto com o handler de fluxo quando quiser enviar os mesmos registros tanto ao console quanto a um arquivo.
Como registrar mensagens em stdout com a função logging.basicConfig() em Python
Para uma configuração simples que abrange toda a aplicação, logging.basicConfig() configura o logger raiz. O parâmetro stream seleciona o fluxo de saída; por padrão, o logging usa sys.stderr. Defina-o como sys.stdout para direcionar os registros à saída padrão. level controla quais registros são aceitos pelo logger raiz, e format define o formato de cada linha emitida.
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() é uma conveniência de uso único para configurar o logger raiz. Se outra parte da aplicação já tiver adicionado um handler ao logger raiz, uma chamada posterior manterá essa configuração; portanto, alterar stream nessa chamada não redirecionará a saída. No Python 3.8 ou posterior, force=True remove os handlers existentes do logger raiz antes de aplicar a configuração. Use essa opção somente quando seu código for responsável por substituir a configuração de logging da aplicação; caso contrário, configure o logging uma única vez no ponto de entrada da aplicação.
As opções filename e filemode configuram a saída para um arquivo: filename indica o nome do arquivo, enquanto filemode controla como ele é aberto e, por padrão, usa o modo de anexação ("a"). Não passe filename e stream juntos para basicConfig(); escolha um único destino nessa configuração. Para enviar registros tanto à saída padrão quanto a um arquivo, use handlers separados, como mostrado abaixo. Além disso, basicConfig() só configura o logger raiz quando ele ainda não tem handlers, a menos que force=True seja usado (opção disponível no Python 3.8 ou posterior).
Como registrar mensagens em stdout com a função logging.StreamHandler() em Python
Use um handler explícito quando precisar controlar um logger nomeado ou combinar destinos. Por padrão, logging.StreamHandler() escreve em sys.stderr; por isso, passe sys.stdout explicitamente. Os níveis do logger e do handler afetam quais registros são emitidos: um registro precisa ser aceito por ambos. Este exemplo cria um handler para stdout e outro para um arquivo e, em seguida, adiciona os dois ao mesmo 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
Cada handler formata o registro e o escreve em seu próprio destino. O arquivo é criado no diretório temporário do sistema, e mode="w" substitui o arquivo de exemplo a cada execução. Em uma aplicação de longa duração, configure os handlers uma única vez em vez de adicioná-los repetidamente; handlers duplicados podem fazer cada registro aparecer mais de uma vez. Em produção, gerencie o caminho do arquivo e o ciclo de vida dos handlers de acordo com a aplicação.
Conclusão
Use logging.basicConfig() com stream=sys.stdout para configurar rapidamente o logger raiz. Escolha logging.StreamHandler(sys.stdout) quando precisar controlar um logger nomeado, personalizar as configurações do handler ou usar vários destinos. Um StreamHandler sem um fluxo explícito escreve em stderr, e o registro simultâneo no console e em um arquivo exige handlers separados para o fluxo e para o arquivo.