Como registrar o nome do arquivo de origem e o número da linha no Python


123

É possível decorar / estender o sistema de log padrão do python, para que, quando um método de log for chamado, ele também registre o arquivo e o número da linha em que foi chamado ou talvez o método que o chamou?

Respostas:


227

Claro, verifique os formatadores nos documentos de log. Especificamente, as variáveis ​​lineno e nome do caminho.

% (nome do caminho) s Nome completo do arquivo de origem em que a chamada de log foi emitida (se disponível).

% (filename) s Parte do nome do arquivo do nome do caminho.

% (module) s Module (parte do nome do nome do arquivo).

% (funcName) s Nome da função que contém a chamada de log.

% (lineno) d Número da linha de origem em que a chamada de log foi emitida (se disponível).

Parece algo como isto:

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')

1
E, sim, a bagunça maiúscula / minúscula nas variáveis ​​precisa ser considerada.
Tom Pohl

1
Caso contrário, referido como "estojo de camelo muito mal implementado".
Jon Spencer

80

Além da resposta muito útil de Seb , aqui está um trecho de código útil que demonstra o uso do criador de logs com um formato razoável:

#!/usr/bin/env python
import logging

logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")

Gera esta saída:

2017-06-06:17:07:02,158 DEBUG    [log.py:11] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred

5
Use isso para obter mais detalhes: formatter = logging. % (message) s ')
Girish Gupta

existe uma maneira de mudar apenas em um lugar na parte superior do código se as mensagens de log são impressas ou não? Eu gostaria de dois modos, um com muitas impressões para ver exatamente o que o programa faz; e uma, para quando estiver estável o suficiente, onde nenhuma saída seja mostrada.
Marie. P.

3
@ Marie.P. não faça perguntas diferentes nos comentários. A resposta é o nível de log.
bugmenot123

4

Para desenvolver o exposto de uma maneira que envia o log de depuração para o padrão:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)

logging.debug("I am sent to standard out.")

Colocar o acima em um arquivo chamado debug_logging_example.pyproduz a saída:

[debug_logging_example.py:14 -             <module>() ] I am sent to standard out.

Então, se você deseja desativar o logoff, comentar root.setLevel(logging.DEBUG).

Para arquivos únicos (por exemplo, tarefas de classe), achei essa uma maneira muito melhor de fazer isso, em vez de usar print()instruções. Onde ele permite desativar a saída de depuração em um único local antes de enviá-la.


1

Para desenvolvedores que usam PyCharm ou Eclipse pydev, o seguinte produzirá um link para a fonte da instrução de log na saída do log do console:

import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))


log.debug("hello logging linked to source")

Consulte Hiperlinks do arquivo de origem Pydev no console do Eclipse para discussão e histórico mais longos.


0
# your imports above ...


logging.basicConfig(
    format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in 
    function %(funcName)s] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)

# your classes and methods below ...
# An naive Sample of usage:
try:
    logger.info('Sample of info log')
    # your code here
except Exception as e:
    logger.error(e)

Diferente das outras respostas, isso registrará o caminho completo do arquivo e o nome da função que pode ter ocorrido um erro. Isso é útil se você tiver um projeto com mais de um módulo e vários arquivos com o mesmo nome distribuídos nesses módulos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.