Cómo registrar el nombre del archivo de origen y el número de línea en Python

¿Es posible decorar / extender el sistema de registro estándar de Python, de modo que cuando se invoca un método de registro también se registre el archivo y el número de línea donde se invocó o tal vez el método que lo invocó?

Claro, compruebe formateadores en documentos de registro. Específicamente las variables lineno y pathname.

% (ruta de acceso) s Ruta completa del archivo de origen donde se emitió la llamada de registro (si está disponible).

% (nombre de archivo) s Parte del nombre de archivo de la ruta de acceso.

% (módulo) s Módulo (parte del nombre del nombre de archivo).

% (funcName) s Nombre de la función que contiene la llamada de registro.

% (lineno) d Número de línea de origen donde se emitió la llamada de registro (si está disponible).

Parece algo como esto:

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

En la parte superior de la muy útil respuesta de Seb , aquí hay un útil fragmento de código que muestra el uso del registrador con un formato razonable:

 #!/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") 

Genera esta salida:

 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 

Para construir sobre lo anterior de una manera que envíe el registro de depuración a la salida estándar:

 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) 

Luego, si desea desactivar ese comentario, root.setLevel(logging.DEBUG) .

Para archivos individuales (por ejemplo, asignaciones de clase), he encontrado que esta es una forma mucho mejor de hacerlo, en lugar de usar sentencias print() . Donde le permite desactivar la salida de depuración en un solo lugar antes de enviarla.