Conceptos básicos de registro de Python

C

Introducción

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 o logger.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.

Para 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:

2018-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:

import 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.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad