Categorías
Python

Entrevista con Marlene comunidad Python Mhangami

 

Tabla de Contenidos

  • El registro Módulo
  • configuraciones básicas
  • Formateo de la variable OutputLogging DataCapturing trazas de la pila
  • registro de datos variables
  • Captura de trazas de la pila Clases
  • y funciones
  • La utilización de controladores
  • otros métodos de configuración
  • Keep calma y leer el registro de variables Registros
  • datos
  • Captura de trazas de la pila

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: registro en Python

El registro es una herramienta muy útil en la caja de herramientas de un programador. Puede ayudar a desarrollar una mejor comprensión del flujo de un programa y descubrir escenarios que puede que ni siquiera han pensado durante el desarrollo.

registros proporcionan a los desarrolladores un par de ojos extra que están constantemente buscando en el flujo que una aplicación está atravesando. Pueden almacenar información, como qué usuario o IP acceder a la aplicación. Si se produce un error, entonces se puede proporcionar más conocimientos que un seguimiento de la pila por lo que le dice el estado del programa era antes de que llegó a la línea de código donde ocurrió el error.

Al iniciar la sesión de datos útiles a partir de los lugares adecuados, no sólo puede depurar errores con facilidad, pero también utilizar los datos para analizar el rendimiento de la aplicación al plan de escalamiento o mirar los patrones de uso de plan de marketing.

Python proporciona un sistema de registro como parte de su biblioteca estándar, por lo que puede agregar rápidamente el registro a su aplicación. En este artículo, usted aprenderá por qué el uso de este módulo es la mejor manera de añadir el registro a su aplicación, así como la forma de empezar a trabajar rápidamente, y obtendrá una introducción a algunas de las características avanzadas disponibles. Bono

gratuito: 5 pensamientos sobre Python Maestría, un curso gratuito para los desarrolladores de Python que muestra la hoja de ruta y la mentalidad que necesita para tomar sus habilidades de Python al siguiente nivel.

El registro Módulo

El módulo de registro de Python es un módulo listo para usar y potente que está diseñado para satisfacer las necesidades de los principiantes, así como los equipos de la empresa. Es utilizado por la mayoría de los terceros bibliotecas de Python, por lo que se puede integrar los mensajes de registro con los de las bibliotecas para producir un registro homogéneo para su aplicación.

Añadir registro cronológico de su programa de Python es tan fácil como esto:

import logging

Con el módulo de registro importados, puede usar algo que se llama un “registrador” para registrar los mensajes que desea ver. Por defecto, hay 5 niveles estándar que indica la gravedad de los acontecimientos. Cada uno tiene un método correspondiente que se puede utilizar para registrar eventos en ese nivel de severidad. Los niveles definidos, con el fin de aumentar la gravedad, son los siguientes:

  • DEBUG
  • INFO
  • ADVERTENCIA
  • ERROR
  • CRÍTICO

El módulo de registro le proporciona un registrador predeterminado que le permite empezar sin necesidad hacer mucho configuración. Los métodos correspondientes para cada nivel pueden ser llamados como se muestra en el siguiente ejemplo:

import logging

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

La salida del programa anterior se vería así:

WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

la salida muestra el nivel de gravedad antes de cada mensaje junto con la raíz, que es el nombre el módulo de registro da a su registrador de forma predeterminada. (Registradores se discuten en detalle en secciones posteriores.) Este formato, que muestra el nivel, nombre, y el mensaje separados por dos puntos (:), es el formato de salida predeterminada que puede ser configurado para incluir cosas como fecha y hora, número de línea, y otros detalles.

en cuenta que la depuración () e información (mensajes) no recibió registran. Esto es porque, por defecto, el módulo de registro registra los mensajes con un nivel de gravedad de ADVERTENCIA o superior. Puede cambiar eso mediante la configuración del módulo de registro para registrar eventos de todos los niveles, si quieres. También puede definir sus propios niveles de gravedad cambiando configuraciones, pero por lo general no es recomendable, ya que puede causar confusión con los registros de algunas bibliotecas de terceros que pueda estar utilizando.

configuraciones básicas

Puede utilizar el basicConfig (** kwargs ) método para configurar el registro:

“Usted se dará cuenta de que el módulo de registro Styleguide rompe PEP8 y usos camelCase convenciones de nombres. Esto se debe a que fue adoptado de Log4j, una utilidad de registro en Java. Es un problema conocido en el paquete, pero en el momento en que se decidió añadir a la biblioteca estándar, que ya había sido adoptado por los usuarios y cambiándolo a los requisitos PEP8 Conoce podría causar problemas de compatibilidad hacia atrás “. (Fuente)

Algunos de los parámetros que se utilizan comúnmente para basicConfig () son los siguientes: Nivel

  • : El registrador de la raíz se establece en el nivel de gravedad específica.
  • Nombre del archivo: Esto especifica el archivo.
  • fileMode: Si no se da el nombre de archivo, el archivo se abre en este modo. El valor predeterminado es una, lo que significa anexión. Formato
  • : Este es el formato del mensaje de registro.

Al utilizar el parámetro de nivel, se puede establecer el nivel de los mensajes de registro que desea grabar. Esto se puede hacer haciendo pasar una de las constantes disponibles en la clase, y esto permitiría que todas las llamadas de registro en o por encima de ese nivel que estar conectado. He aquí un ejemplo:

import logging

logging.basicConfig(level=logging.DEBUG)
logging.debug('This will get logged')
DEBUG:root:This will get logged

Todos los eventos en o sobre el nivel de depuración ahora ser registrados.

Del mismo modo, para el registro en un archivo en lugar de la consola, nombre de archivo y fileMode se puede utilizar, y se puede decidir el formato del mensaje utilizando el formato. El siguiente ejemplo muestra el uso de los tres:

import logging

logging.basicConfig(filename='app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('This will get logged to a file')
root - ERROR - This will get logged to a file

El mensaje se verá como este, pero se escriben en un archivo llamado app.log vez de la consola. El fileMode está ajustado en W, lo que significa que se abre el archivo de registro en “modo de escritura” cada vez basicConfig () se llama, y ​​cada ejecución del programa volverá a escribir el archivo. La configuración por defecto para fileMode es una, que es append.

Puede personalizar el registrador de la raíz aún más mediante el uso de más parámetros para basicConfig (), que se puede encontrar aquí.

Cabe señalar que llamar basicConfig () para configurar el registrador de la raíz sólo funciona si el registrador de la raíz no se ha configurado antes. Básicamente, esta función sólo puede ser llamado una vez.

debug (), información (), la alerta (), error () y crítico () también llamada basicConfig () sin argumentos automáticamente si no se ha llamado antes. Esto significa que después de la primera vez de las funciones anteriores se llama, ya no se puede configurar el registrador de la raíz, ya que habrían llamado la función basicConfig () internamente.

El ajuste predeterminado en basicConfig () es para configurar el registrador de escribir en la consola con el siguiente formato:

ERROR:root:This is an error message

Formateo de la salida

Si bien puede pasar cualquier variable que se puede representar como una cadena de su programa como una mensaje a sus registros, hay algunos elementos básicos que ya forman parte de la LogRecord y se pueden agregar fácilmente al formato de salida. Si desea registrar el ID del proceso, junto con el nivel y el mensaje, puede hacer algo como esto: Formato

import logging

logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')
logging.warning('This is a Warning')
18472-WARNING-This is a Warning

puede tener una cadena con LogRecord atributos en cualquier arreglo te gusta. Toda la lista de atributos disponibles se puede encontrar aquí.

He aquí otro ejemplo donde se puede agregar la información de fecha y hora:

import logging

logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
logging.info('Admin logged in')
2018-07-11 20:12:06,288 - Admin logged in

% (asctime) s agrega el momento de la creación de la LogRecord. El formato se puede cambiar usando el atributo DATEFMT, que utiliza el mismo lenguaje de formato como las funciones de formato de fecha y hora en el módulo, como time.strftime ():

import logging

logging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logging.warning('Admin logged out')
12-Jul-18 20:53:19 - Admin logged out

Puede encontrar la guía aquí.

registro de datos variables

En la mayoría de los casos, que se quiere incluir información dinámica desde su aplicación en los registros. Usted ha visto que los métodos de explotación forestal toman una cadena como argumento, y que podría parecer natural para dar formato a una cadena con datos variables en una línea separada y pasarlo al método de registro. Pero en realidad esto puede hacerse directamente mediante el uso de una cadena de formato para el mensaje y anexar los datos variables como argumentos. He aquí un ejemplo:

import logging

name = 'John'

logging.error('%s raised an error', name)
ERROR:root:John raised an error

Los argumentos que se pasan al método serían incluidos como datos variables en el mensaje.

Aunque se puede usar cualquier estilo de formato, el F-cadenas introducidas en Python 3.6 son una manera impresionante de cadenas de formato, ya que pueden ayudar a mantener el corto formato y fácil de leer:

import logging

name = 'John'

logging.error(f'{name} raised an error')
ERROR:root:John raised an error

Captura de trazas de la pila

El módulo de registro también le permite capturar las trazas de pila completo en una aplicación. información de excepción puede ser capturado si el parámetro exc_info se pasa como Verdadero, y las funciones de registro se llaman así:

import logging

a = 5
b = 0

try:
c = a / b
except Exception as e:
logging.error("Exception occurred", exc_info=True)
ERROR:root:Exception occurred
Traceback (most recent call last):
File "exceptions.py", line 6, in
c = a / b
ZeroDivisionError: division by zero
[Finished in 0.2s]

Si exc_info no se establece en True, la salida del programa anterior no nos dice nada acerca de la excepción, el cual, en un escenario del mundo real, puede no ser tan simple como un ZeroDivisionError. Imagínese tratando de depurar un error en una base de código complicado con un registro que muestra solamente esto:

ERROR:root:Exception occurred

Aquí está una extremidad rápida: si el registro de un gestor de excepciones, utiliza el método logging.exception (), que registra un mensaje con error de nivel y añade información de excepción al mensaje. Para decirlo más simplemente, llamar logging.exception () es como llamar logging.error (exc_info = Verdadero). Pero dado que este método siempre volcados de información de excepción, sólo debería ser llamado desde un controlador de excepciones. Echar un vistazo a este ejemplo:

import logging

a = 5
b = 0
try:
c = a / b
except Exception as e:
logging.exception("Exception occurred")
ERROR:root:Exception occurred
Traceback (most recent call last):
File "exceptions.py", line 6, in
c = a / b
ZeroDivisionError: division by zero
[Finished in 0.2s]

Usando logging.exception () mostraría un registro en el nivel de error. Si usted no quiere eso, se puede llamar a cualquiera de los otros métodos de registro de depuración () a crítica () y pasar el parámetro exc_info como verdadero. Clases y funciones

Así

ahora, hemos visto el registrador predeterminado denominado raíz, que es utilizado por el módulo de registro cada vez que sus funciones son llamadas directamente como esto: logging.debug (). Se puede (y debe) definir su propio registrador mediante la creación de un objeto de la clase Logger, especialmente si su aplicación tiene múltiples módulos. Vamos a echar un vistazo a algunas de las clases y funciones en el módulo.

Los más utilizados clases definidas en el módulo de registro son los siguientes:

  • Logger: Esta es la clase cuyos objetos se utilizará en el código de la aplicación directamente a llamar a las funciones.
  • LogRecord: registradores de crear automáticamente objetos LogRecord que tienen toda la información relacionada con el evento que se registran, al igual que el nombre del registrador, la función, el número de línea, el mensaje, y más.
  • Handler: Manipuladores de enviar el LogRecord al destino de salida requerida, al igual que la consola o un archivo. Handler es una base para subclases como StreamHandler, FileHandler, SMTPHandler, HTTPHandler, y más. Estas subclases envían las salidas de registro correspondientes a los destinos, como sys.stdout o un archivo de disco.
  • Formateador: Aquí es donde se especifica el formato del resultado especificando una cadena de formato que las listas de los atributos que la salida deben contener.

Logger: Esta es la clase cuyos objetos se utilizará en el código de la aplicación directamente a llamar a las funciones.

LogRecord: registradores de crear automáticamente objetos LogRecord que tienen toda la información relacionada con el evento que se registra, al igual que el nombre del registrador, la función, el número de línea, el mensaje, y más.

Handler: Manipuladores de enviar el LogRecord al destino de salida requerida, al igual que la consola o un archivo. Handler es una base para subclases como StreamHandler, FileHandler, SMTPHandler, HTTPHandler, y más. Estas subclases envían las salidas de registro correspondientes a los destinos, como sys.stdout o un archivo de disco.

Formateador: Aquí es donde se especifica el formato de la salida mediante la especificación de un formato de cadena que las listas de los atributos que la salida deben contener.

Fuera de estos, sobre todo frente a los objetos de la clase Logger, que se crean instancias utilizando el logging.getLogger función de nivel de módulo (nombre). Varias llamadas a getLogger () con el mismo nombre, se devuelve una referencia al mismo objeto Logger, lo que nos ahorra el paso de los objetos del registrador a todas las partes donde más se necesita. He aquí un ejemplo:

import logging

logger = logging.getLogger('example_logger')
logger.warning('This is a warning')
This is a warning

Esto crea un registrador personalizado denominado example_logger, pero a diferencia del registrador de la raíz, el nombre de un registrador de costumbre no es parte del formato de salida por defecto y tiene que ser añadido a la configuración. Configurándolo para un formato para mostrar el nombre del registrador daría una salida como esta:

WARNING:example_logger:This is a warning

Una vez más, a diferencia del registrador de la raíz, un registrador de costumbre no se puede configurar mediante basicConfig (). Usted tiene que configurarlo usando manipuladores y Formateadores:

“Se recomienda que utilizamos registradores de nivel de módulo pasando __name__ como el parámetro de nombre a getLogger () para crear un objeto registrador como el nombre del registrador sí nos decía desde donde se registran los eventos. __name__ es un especial de variable incorporada en Python que se evaluará como el nombre del módulo actual “. (Fuente)

La utilización de controladores

Manipuladores entran en escena cuando se quiere configurar sus propios madereros y enviar los registros a varios lugares cuando se generan. Manipuladores envían los mensajes de registro a los destinos configurados como el flujo de salida estándar o un archivo o a través de HTTP o en su correo electrónico a través de SMTP.

Un registrador de que se cree puede tener más de un controlador, lo que significa que usted puede configurarlo para que se guarden en un archivo de registro y enviarlo por correo electrónico. madereros

desea, también puede establecer el nivel de gravedad de los manipuladores. Esto es útil si desea configurar varios controladores para el mismo registrador, pero desea diferentes niveles de gravedad para cada uno de ellos. Por ejemplo, es posible que desee registros con el nivel de advertencia y de arriba para ser registrados en la consola, pero todo con el error y superiores también deben ser guardados en un archivo. Aquí hay un programa que hace que:

# logging_example.py

import logging

# Create a custom logger
logger = logging.getLogger(__name__)

# Create handlers
c_handler = logging.StreamHandler()
f_handler = logging.FileHandler('file.log')
c_handler.setLevel(logging.WARNING)
f_handler.setLevel(logging.ERROR)

# Create formatters and add it to handlers
c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
c_handler.setFormatter(c_format)
f_handler.setFormatter(f_format)

# Add handlers to the logger
logger.addHandler(c_handler)
logger.addHandler(f_handler)

logger.warning('This is a warning')
logger.error('This is an error')
__main__ - WARNING - This is a warning
__main__ - ERROR - This is an error

aquí, logger.warning () es la creación de un LogRecord que contiene toda la información del evento y pasarlo a todos los gestores que tiene: c_handler y f_handler.

c_handler es un StreamHandler con nivel de advertencia y toma la información de la LogRecord para generar una salida en el formato especificado y lo imprime en la consola. f_handler es un FileHandler con error de nivel, y no tiene en cuenta este LogRecord como su nivel es ADVERTENCIA.

Cuando logger.error () se llama, se comporta exactamente igual que antes c_handler y f_handler consigue un LogRecord en el nivel de error, por lo que procede a generar una salida al igual que c_handler, pero en lugar de imprimir a la consola, que lo escribe en el archivo especificado en este formato:

2018-08-03 16:12:21,723 - __main__ - ERROR - This is an error

el nombre del registrador correspondiente a la variable __name__ se registra como __main__, que es el nombre de Python asigna al módulo donde la ejecución se inicia. Si este archivo es importado por algún otro módulo, entonces la variable __name__ correspondería a su nombre logging_example . Así es como se vería:

# run.py

import logging_example
logging_example - WARNING - This is a warning
logging_example - ERROR - This is an error

otros métodos de configuración

Puede configurar el registro como se muestra anteriormente, utilizando las funciones del módulo y de clase o mediante la creación de un archivo de configuración o un diccionario y carga usando fileConfig () o dictConfig () respectivamente. Estos son útiles en caso de que desee cambiar su configuración de registro en una aplicación en ejecución.

Aquí está un ejemplo de configuración de archivos:

[loggers]
keys=root,sampleLogger

[handlers]
keys=consoleHandler

[formatters]
keys=sampleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sampleLogger]
level=DEBUG
handlers=consoleHandler
qualname=sampleLogger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=sampleFormatter
args=(sys.stdout,)

[formatter_sampleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

En el archivo de arriba, hay dos registradores, uno manipulador, y un formateador. Después se definen sus nombres, que se configuran mediante la adición de las palabras registrador, manipulador, y el formateador antes de que sus nombres separados por un guión bajo.

Para cargar este archivo de configuración, usted tiene que utilizar fileConfig ():

import logging
import logging.config

logging.config.fileConfig(fname='file.conf', disable_existing_loggers=False)

# Get the logger specified in the file
logger = logging.getLogger(__name__)

logger.debug('This is a debug message')
2018-07-13 13:57:45,467 - __main__ - DEBUG - This is a debug message

La ruta del archivo de configuración se pasa como un parámetro al método fileConfig (), y los disable_existing_loggers parámetro se utiliza para mantener o deshabilitar los registradores que están presentes cuando la función se llama. Su valor predeterminado es True si no se mencionan.

Aquí está la misma configuración en un formato YAML para el enfoque diccionario:

version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
loggers:
sampleLogger:
level: DEBUG
handlers: [console]
propagate: no
root:
level: DEBUG
handlers: [console]

Aquí hay un ejemplo que muestra cómo cargar configuración de un archivo YAML:

import logging
import logging.config
import yaml

with open('config.yaml', 'r') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)

logger = logging.getLogger(__name__)

logger.debug('This is a debug message')
2018-07-13 14:05:03,766 - __main__ - DEBUG - This is a debug message

Mantener la calma y leer los registros

El módulo de registro se considera ser muy flexible. Su diseño es muy práctico y debe ajustarse a su caso de uso fuera de la caja. Puede añadir registro básico para un proyecto pequeño, o puede ir tan lejos como la creación de sus propios niveles de registro personalizadas, clases de controlador, y más si se está trabajando en un proyecto grande.

Si usted no ha estado utilizando el registro en sus aplicaciones, ahora es un buen momento para empezar. Cuando se hace bien, la tala seguramente eliminar una gran cantidad de fricción de su proceso de desarrollo y ayuda a encontrar oportunidades para tomar su aplicación al siguiente nivel.

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: registro en Python

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *