Logueando como un pro

porque llenar un script con prints sigue siendo

HOLA

me llamo

Javi

Backend Developer en Mozio

settings.LOGGING

Trabajamos con Django

=

print() VS logging

Tarea

Herramienta

Mostrar en consola detalles de pequeños scripts

print()

Mostrar información durante la ejecución normal de un programa

logging.debug() logging.info()

Lanzar avisos

warnings.warn()
logging.warning()

Informar de errores de ejecución

logging.error()
logging.exception()
logging.critical()

Incluído en la biblioteca estándar desde la versión 2.3

¿Para qué es útil?

Mensajes con distintos niveles de importancia

Formatos de mensajes configurables

Configuración separada por grupos de mensajes

Distintos destinos para los mensajes

Niveles / Levels

Registradores / Loggers

Formateadores / Formatters

Manejadores / Handlers

¿Cuáles son sus componentes principales?

Niveles / Levels

Registradores / Loggers

Formateadores / Formatters

Manejadores / Handlers

DEBUG, INFO, WARNING, ERROR, CRITICAL

        

Cajones/canales a los que enviar mensajes

Cada uno tiene un nombre (string)

Tienen jerarquía: abuelo.padre.hijo

Definen el formato final del mensaje

Permiten incluir informacion extra útil: nombre del logger, nivel, marcas de tiempo, función, línea de código, etc.

Controlan el destino del mensaje: consola, fichero, fichero auto-rotable, socket de red, /dev/null

Y un puñado de "trampas"

¿Trampas? ¡Trampas!

Registradores / Loggers

Formateadores / Formatters

Manejadores / Handlers

El módulo define automáticamente un registrador `root`

En la jerarquía, es siempre el padre del resto de registradores

Sin ningún Manejador asignado por defecto.

Pero lo hace automáticamente si se procesa un mensaje desde el módulo, pej. logging.debug()

Por defecto utilizan formateo de cadenas antiguo (%)

Pero no se usa el operador %, sino que se pasan como parámetros

StreamHandler, FileHandler y NullHandler se definen en logging, el resto en logging.handlers ¯\_(ツ)_/¯

¿Cómo funciona?

Mensaje

Registrador

Nivel

Padre
No definido

Manejador

Mayor o igual

Nivel

Menor
Mayor o igual

Ignorar

Menor

Ignorar

Padre
No definido

Formateador

2017-09-19 16:57:55,840 | WARNING  | Aviso

¿Cómo puedo aprovecharlo?

Control de niveles

Diferentes formatos

Varios destinos

¿Cómo se configura?

A través de la API

FileConfig

DictConfig

En instancias, con logger.addHandler(), logger.setLevel(), etc.

A nivel de módulo logging.basicConfig()

El método recomendado: un diccionario "de toda la vida"

Basado en configparser

El más antiguo y sin soporte para algunas características

Y también ...

Se puede guardar en un fichero json/yaml y convertirlo a dict

¿Más Trampas? ¡Más Trampas!

A través de la API

DictConfig

logging.basicConfig() sólo sirve para el Registrador `root`

Y sólo si no tiene ya asignado algún Manejador

Llamar a logging.debug(), logging.info()... también llama a .basicConfig()

Llamar a instancia.debug() no configura nada, pero igual saca el mensaje por un manejador de ultimo recurso que escribe a STDERR

El único parametro requerido es `version` y el único valor admitido es 1.

`disable_existing_loggers`: True [por defecto] Deshabilita todos los loggers cuyo nombre o el de sus antecesores no hayan sido explicitamente configurados. Incluído el `root`

¿Cómo vamos de tiempo?

Ejemplos de configuración

Entendiendo el ajuste LOGGING de Django

¡Muchas gracias!

Si tenéis cualquier duda este es un buen momento

@gooleres

flickr.com/photos/javi_romero/

bit.do/cutre-2

github.com/javiromero/pycones2017

Logueando como un pro: porque llenar un script con prints sigue siendo cutre

By Javi Romero

Logueando como un pro: porque llenar un script con prints sigue siendo cutre

PyconES 2017

  • 2,154