Introducción
Contenido
El registro lo ayuda a realizar un seguimiento de los eventos que ocurren durante la ejecución de su código, que luego se puede usar en el futuro con fines de depuración. Proporciona una mejor imagen del flujo de la aplicación y ayuda a los desarrolladores a rastrear el origen de los errores que ocurren durante la ejecución de su código, mejorando así la capacidad de mantenimiento de la aplicación.
En Python, la biblioteca estándar de Python proporciona la mayoría de las funciones de registro básicas. Por lo tanto, puede agregar el registro a su aplicación fácilmente sin configuraciones adicionales. El módulo de registro estándar permite al desarrollador escribir mensajes de estado en un archivo o en cualquier otro flujo de salida.
El módulo de registro
los logging
El módulo está disponible en entornos Python de forma predeterminada y proporciona un registrador predeterminado llamado «root». Define las funciones y clases que implementan la funcionalidad de registro.
La API de registro proporcionada por la biblioteca estándar le permite incluir sus propios mensajes en el registro de la aplicación, así como la integración con mensajes de módulos de terceros. También proporciona un mecanismo para anotar los mensajes de registro con el origen, la marca de tiempo, la gravedad y otros metadatos, lo que ayuda en el análisis del registro.
Tipos de registro (niveles de registro)
Cada mensaje de registro está asociado con un nivel de gravedad, que es un número entero que se utiliza para señalar la criticidad de los eventos registrados. El módulo de registro tiene una función auxiliar para cada nivel de registro; estos se nombran de acuerdo con el nivel de registro. A continuación, se muestra una lista de niveles de registro junto con su uso recomendado.
- Depurar (
logger.debug
): Proporciona una salida muy detallada. Se utiliza para diagnosticar problemas. - Información (
logger.info
): Proporciona información sobre la ejecución correcta. Confirma si las cosas están funcionando como se esperaba. - Advertencia (
logger.warn
ologger.warning
): Emite una advertencia con respecto a un problema que podría ocurrir en el futuro o una falla recuperable. - Error (
logger.error
): Indica un problema en el software ya que no se está ejecutando como se esperaba. - Crítico (
logger.critical
): Indica un error grave que podría detener la ejecución del programa.
De forma predeterminada, el registrador raíz está configurado para informar todos los mensajes en el nivel de Advertencia o por encima de él; cualquier mensaje por debajo de este nivel se filtra. Sin embargo, es posible configurar el módulo explícitamente para que sea más o menos selectivo en el filtrado.
Te puede interesar:Funciones anidadas de PythonPara agregar el registro a una secuencia de comandos de Python, simplemente importe el módulo usando import logging
, y después de una importación exitosa, el script puede registrar mensajes usando el logging.*
métodos, como logging.debug()
.
Aquí puede ver un ejemplo simple del módulo de registro en acción:
import logging
logging.warning("Caution: This is the root logger!")
Salida:
WARNING:root:Caution: This is the root logger!
Objetos del registrador
los logging
El módulo permite al usuario crear múltiples objetos de registro. Se pueden usar diferentes tipos de objetos de registro para obtener un control detallado sobre cómo las diferentes partes de una aplicación de Python registran sus mensajes; por ejemplo, la aplicación principal de Python puede usar el root
logger mientras que las bibliotecas de terceros utilizadas desde esta aplicación pueden usar sus propios objetos de registrador con sus propias configuraciones.
Mientras usa el predeterminado root
funciones del registrador, podemos llamar a las funciones directamente, por ejemplo, logging.debug()
. Es posible configurar su propio registrador creando un objeto del Logger
class, y esto puede ser útil si su aplicación tiene varios módulos.
Echemos un vistazo a algunas de las clases y funciones en el logging
módulo. Las clases básicas y sus funciones son las siguientes:
- Registradores: expone la interfaz que utiliza la aplicación. Los objetos de esta clase se utilizan directamente para llamar a las funciones en la aplicación.
- Controladores: envía mensajes de registro a la ubicación adecuada en el software, como una consola de salida estándar, un archivo, a través de HTTP o incluso al correo electrónico (a través de SMTP).
- Filtros: brinda un control detallado sobre la elección de los registros de registro para mostrar.
- Formateadores: especifica el diseño final de los registros de registro, especificando los atributos que debe contener la salida.
De estos, los objetos del Logger
class se utilizan con mayor frecuencia.
Para crear un nuevo registrador, podemos usar el logging.getLogger()
método. En el siguiente script, registramos errores usando el root
registrador así como nuestro registrador personalizado my_logger
.
import logging
my_logger = logging.getLogger("My Logger")
logging.error("Error: Root Log")
my_logger.error("Error: My Logger log")
Salida:
ERROR:root:Error: Root Log
ERROR:My Logger:Error: My Logger log
Cada mensaje de registro no solo indicará la fuente, el objeto de registro a través del cual se registró, sino que mostrará un mensaje basado en la configuración de ese objeto de registro.
En las siguientes secciones, veremos las diversas opciones de configuración de los objetos del registrador.
Registro en un archivo frente a la salida estándar
De forma predeterminada, los objetos del registrador envían los registros a la salida estándar. Puedes usar basicConfig()
método para cambiar este y otros parámetros. A continuación se muestra una lista de parámetros para basicConfig
método:
- nivel: establezca el registrador un nivel de gravedad. No se registrará ningún mensaje por debajo de este nivel de gravedad.
- nombre de archivo: el nombre del archivo donde se escriben los registros.
- filemode: el modo en el que se abrirá el archivo especificado, si lo hay.
- formato: especifica el formato del mensaje de registro. Esta es una cadena con
LogRecord
atributos.
LogRecord
El objeto contiene la información de los eventos que se registran, como el número de línea, la hora, el nombre del registrador, etc. Hablar del objeto LogRecord está fuera del alcance de este artículo, pero hay más información disponible. aquí.
A continuación se muestra un resumen de los pasos a seguir para registrar eventos de registro en un archivo:
- Importe el módulo de registro.
- Configure el registrador usando
basicConfig
método - Creando un objeto registrador.
- Configuración del valor umbral del registrador.
- Utilice los métodos de registro.
Esto se puede entender mejor con un ejemplo:
# Filename: test_logger.py
import logging
# Create a logger object
logger = logging.getLogger()
# Configure logger
logging.basicConfig(filename="test.log", format="%(filename)s: %(message)s", filemode="w")
# Setting threshold level
logger.setLevel(logging.DEBUG)
# Use the logging methods
logger.debug("This is a debug message")
logger.info("For your info")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
El script anterior creará un archivo «test.log». El archivo contendrá la siguiente información de registro:
test_logger.py: This is a debug message
test_logger.py: For your info
test_logger.py: This is a warning message
test_logger.py: This is an error message
test_logger.py: This is a critical message
Fecha / hora en mensajes de registro
Para mostrar la fecha y hora de la ocurrencia de un evento, puede usar %(asctime)s
en su cadena de formato en basicConfig()
función. Por ejemplo:
import logging
logging.basicConfig(format="%(asctime)s %(message)s")
logging.warning('is the time the Admin logged out.')
Salida:
Te puede interesar:Resumir textos con NLTK en Python2018-12-17 10:52:15,463 is the time the Admin logged out.
Si desea cambiar la forma en que aparece la fecha / hora, puede configurarlo usando el datefmt
parámetro de la basicConfig
método.
Variables de registro
En las aplicaciones del mundo real, necesitamos generar registros de acuerdo con los cambios dinámicos que ocurren en nuestra aplicación. Como se ve en el ejemplo anterior, los métodos de registro toman una cadena como argumento. Además, podemos incluir variables y formatear la cadena con marcadores de posición y luego pasarla al método de registro. En tiempo de ejecución, el valor de las variables se mostrará en los mensajes de registro.
Aquí hay un ejemplo de eso usando formato de cadena:
import logging
status = "connection unavailable"
logging.error("System reported: %s", status)
Salida:
ERROR:root:System reported: connection unavailable
Comenzar con Python 3.6 f-Strings se puede usar como una alternativa a los especificadores de formato de cadena, por lo que el código se puede leer fácilmente cuando hay múltiples parámetros. Con f-strings, puede especificar cualquier expresión de Python como parte del mensaje, que se evalúan durante el tiempo de ejecución y el resultado se incrusta en los mensajes de registro.
El ejemplo anterior se puede reescribir usando una cadena f como:
Te puede interesar:Manejo de archivos en Pythonimport logging
status = "connection unavailable"
logging.error(f'System reported: {status}')
Seguimiento de la pila de registros
La captura de seguimientos de pila en su aplicación también es compatible con el módulo de registro. Establecer el exc_info
parámetro a True
mientras que llamar a las funciones de registro nos permite capturar la información de la excepción. Al usar esta función, podemos obtener información sobre la excepción que se está manejando actualmente. La información es específica del hilo actual y del marco de pila actual.
import logging
my_list = [1, 2]
try:
print(my_list[3]) # Index out of range
except Exception as e:
logging.error("Caught Exception!", exc_info=True)
Salida:
ERROR:root:Caught Exception!
Traceback (most recent call last):
File "index.py", line 5, in <module>
print(my_list[3]) # Index out of range
IndexError: list index out of range
En caso de que el marco de pila actual no maneje las excepciones, la información se obtiene de su llamador (es decir, el marco de pila que llama) y así sucesivamente hasta que encuentra un marco de pila para manejar la excepción. El marco de pila tiene la información de la excepción manejada más recientemente.
Si la pila no tiene excepciones que se estén manejando, una tupla que tiene None
se devuelve el valor. De lo contrario, la función devuelve el valor de type
(el tipo de excepción que se maneja), valor (parámetro de excepción) y rastreo (el objeto de rastreo que encapsula la pila de llamadas donde ocurrió la excepción originalmente).
Conclusión
El diseño del módulo de registro es muy práctico y proporciona funciones de registro listas para usar que pueden agregar un registro básico a un proyecto pequeño. Puede ampliarse fácilmente mediante el uso de objetos de registro y sus ricas opciones de configuración para satisfacer las necesidades de las aplicaciones más exigentes. Además de los mensajes, el módulo de registro también se puede utilizar para registrar excepciones y apilar seguimientos. Con esto concluye el tutorial básico sobre la implementación del registro en Python.
Te puede interesar:Implementación de Word2Vec con la biblioteca Gensim en Python