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?

digy
fonte

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')
Seb
fonte
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
codeforester
fonte
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.

orangepips
fonte
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.

caracteres
fonte
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.

Hosana Gomes
fonte