0% encontró este documento útil (0 votos)
23 vistas

Py05 Logging Con Python

Este documento describe cómo realizar logging en Python utilizando el módulo logging. Explica cómo generar logs dentro de un único script mediante salida por consola, fichero o ambos. También cubre cómo realizar logging entre varios scripts utilizando un logger raíz común o distintos loggers. El objetivo es registrar eventos de diferentes niveles de criticidad de forma flexible.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
0% encontró este documento útil (0 votos)
23 vistas

Py05 Logging Con Python

Este documento describe cómo realizar logging en Python utilizando el módulo logging. Explica cómo generar logs dentro de un único script mediante salida por consola, fichero o ambos. También cubre cómo realizar logging entre varios scripts utilizando un logger raíz común o distintos loggers. El objetivo es registrar eventos de diferentes niveles de criticidad de forma flexible.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Está en la página 1/ 8

Tabla de contenidos

 
Introducción
 Logging dentro de un único script
Salida por consola
Salida por fichero
Salida por consola y varios fichero
 Logging entre varios scripts

Logging con Python


Opción 1: Utilizar solo el logger root del main scri
Opción 2: Utilizar el logger root creado en el main
Información de sesión

Joaquín Amat Rodrigo


Mayo, 2020

Más sobre ciencia de datos: cienciadedatos.net


(https://cienciadedatos.net)

Introducción

El siguiente notebook contiene ejemplos de cómo registrar logs con


python emplenado el modulo logging .

Por defecto, esto módulo tiene predefinidos 5 niveles para los logs,
ordenados de menor a mayor criticidad:

• DEBUG
• INFO
• WARNING
• ERROR
• CRITICAL

Una vez establecido un determinado nivel, solo se muestran logs de


esa criticidad o superior.

Logging dentro de un único


script

Hacer logging dentro de un único script es la situación más sencilla, ya


que solo es necesario crear un único logger.

Salida por consola


Tabla de contenidos In [17]: # El siguiente script genera un array con 100 números
aleatorios y calcula la suma de todos ellos
 
# ====================================================
Introducción
===========================================
 Logging dentro de un único script
import logging
Salida por consola
import numpy as np
Salida por fichero
Salida por consola y varios fichero # Creación del logger que muestra la información única
 Logging entre varios scripts mente por consola.
Opción 1: Utilizar solo el logger root del main scri
logging.basicConfig(
Opción 2: Utilizar el logger root creado en el mainformat = '%(asctime)-5s %(name)-15s %(levelname)-8
Información de sesión s %(message)s',
level = logging.INFO, # Nivel de los eventos que
se registran en el logger
)

logging.info('Inicio main script')


numeros = np.random.rand(1,100)
logging.info('Números aleatorios simulados')
numeros.sum()
logging.info('Suma calculada')
logging.info('Fin main script')
logging.shutdown()

2020-10-26 10:40:49,393 root INFO Inicio m


ain script
2020-10-26 10:40:49,394 root INFO Números
aleatorios simulados
2020-10-26 10:40:49,395 root INFO Suma cal
culada
2020-10-26 10:40:49,396 root INFO Fin main
script

Salida por fichero


In [18]: # Se eliminan los handlers anteriores
if logging.getLogger('').hasHandlers():
logging.getLogger('').handlers.clear()

In [19]: # El siguiente script genera un array con 100 números


aleatorios y calcula la suma de todos ellos
# ====================================================
===========================================
import logging
import numpy as np

# Creación del logger que muestra la información única


mente por fichero.
logging.basicConfig(
format = '%(asctime)-5s %(name)-15s %(levelname)-8
s %(message)s',
level = logging.INFO, # Nivel de los eventos
que se registran en el logger
filename = "logs_info.log", # Fichero en el que se
escriben los logs
filemode = "a" # a ("append"), en cad
a escritura, si el archivo de logs ya existe,
# se abre y añaden nue
vas lineas.
)

logging.info('Inicio main script')


numeros = np.random.rand(1,100)
logging.info('Números aleatorios simulados')
numeros.sum()
logging.info('Suma calculada')
logging.info('Fin main script')
logging.shutdown()
Tabla de contenidos
 
Introducción Salida por consola y varios fichero
 Logging dentro de un único script
Salida por consola
Salida por fichero
Salida por consola y variosCada
fichero logger puede tener uno o varios handlers. Los handlers son los
 Logging entre varios scripts encargados de gestionar dónde se dirige cada tipo de log. Si se quiere
Opción 1: Utilizar solo el logger root del main scri
que los logs vayan a varios destinos, se tiene que añadir un handler
Opción 2: Utilizar el logger root creado en el main
Información de sesión por cada uno de ellos.
Tabla de contenidos In [20]: import logging
import numpy as np
 
Introducción
# Creación del logger que muestra la información única
 Logging dentro de un único script
mente por fichero.
Salida por consola
#
Salida por fichero ------------------------------------------------------
Salida por consola y varios fichero -----------------------
 Logging entre varios scripts logging.basicConfig(
Opción 1: Utilizar solo el logger root del main scriformat = '%(asctime)-5s %(name)-15s %(levelname)-8
Opción 2: Utilizar el logger root creado en elsmain
%(message)s',
Información de sesión level = logging.INFO, # Nivel de los eventos
que se registran en el logger
filename = "logs_info.log", # Fichero en el que se
escriben los logs
filemode = "a" # a ("append"), en cad
a escritura, si el archivo de logs ya existe,
# se abre y añaden nue
vas lineas.
)

# Nuevos handlers
#
------------------------------------------------------
-----------------------
# Se añaden dos nuevos handlers al root logger, uno pa
ra los niveles de debug o
# superiores y otro para que se muestre por pantalla l
os niveles de info o
# superiores.

# Si el root logger ya tiene handlers, se eliminan ant


es de añadir los nuevos.
# Esto es importante para que los logs no empiezen a d
uplicarse.
if logging.getLogger('').hasHandlers():
logging.getLogger('').handlers.clear()

# Handler nivel debug con salida a fichero


file_debug_handler = logging.FileHandler('logs_debug.l
og')
file_debug_handler.setLevel(logging.DEBUG)
file_debug_format = logging.Formatter('%(asctime)s-%(n
ame)s-%(levelname)s-%(message)s')
file_debug_handler.setFormatter(file_debug_format)
logging.getLogger('').addHandler(file_debug_handler)

# Handler nivel info con salida a consola


consola_handler = logging.StreamHandler()
consola_handler.setLevel(logging.INFO)
consola_handler_format = logging.Formatter('%(asctime)
s-%(name)s-%(levelname)s-%(message)s')
consola_handler.setFormatter(consola_handler_format)
logging.getLogger('').addHandler(consola_handler)

# El siguiente script genera un array con 100 números


aleatorios y calcula la suma de todos ellos
# ====================================================
===========================================
logging.info('Inicio main script')
numeros = np.random.rand(1, 100)
logging.info('Números aleatorios simulados')
numeros.sum()
logging.info('Suma calculada')
logging.info('Fin main script')
logging.shutdown()

2020-10-26 10:40:49,413-root-INFO-Inicio main script


2020-10-26 10:40:49,414-root-INFO-Números aleatorios simu
lados
2020-10-26 10:40:49,414-root-INFO-Suma calculada
2020-10-26 10:40:49,415-root-INFO-Fin main script
Tabla de contenidos
 
Introducción
Logging entre varios
 Logging dentro de un único script
Salida por consola
Salida por fichero
scripts
Salida por consola y varios fichero
 Logging entre varios scripts
Opción 1: Utilizar solo el logger root del main scri
Para almacenar en un mismo fichero los logs
que genera un script y
Opción 2: Utilizar el logger root creado en el main
Información de sesión todas las funciones/clases que se importan en
él (cada una con un su
propio logger), es necesario que los loggers se comuniquen entre ellos
de forma jerárquica.

Para este ejemplo se emplea un main script en el que se importa la


función suma() , que a su vez contiene varios logs.

Opción 1: Utilizar solo el logger root del


main script

En el main script se crea un logger root (es el que crea


logging.basicConfig() por defecto) al que se le añaden nuevos
handlers. En cada función o clases se importa la librería logging y se
emplean sus métodos.

Esta aproximación presenta la ventaja de que no es necesario crear un


logger nuevo en cada función-clase ya que todos los logs son
recopilados por el logger root creado en el main script . La
desventaja es que, como todos los logs son recopilados por el root, no
es posible identificar de qué función-clase proceden (a no ser que se
identifique por el cuerpo del mensaje).

In [21]: # El contenido del archivo funcion_suma.py es:

#import logging
#def suma(a,b):
# if not isinstance(a, (int, float)) \
# or not isinstance(b, (int, float)):
# raise Exception(
# logging.error("a y b deben ser números")
# )
# logging.info('función suma ejecutada')
# return(a+b)
Tabla de contenidos In [22]: # ======================= MAIN SCRIPT ================
============================
 
Introducción
import logging
 Logging dentro de un único script
from funcion_suma import suma # Esta función tiene sus
Salida por consola
propios logs
Salida por fichero
Salida por consola y varios fichero # Definición del logger root
 Logging entre varios scripts #
Opción 1: Utilizar solo el logger root del main scri
------------------------------------------------------
Opción 2: Utilizar el logger root creado en el-----------------------
main
Información de sesión logging.basicConfig(
format = '%(asctime)-5s %(name)-15s %(levelname)-8
s %(message)s',
level = logging.INFO,
filemode = "a"
)

# Nuevos handlers
#
------------------------------------------------------
-----------------------
# Si el root logger ya tiene handlers, se eliminan ant
es de añadir los nuevos.
# Esto es importante para que los logs no empiezen a d
uplicarse.
if logging.getLogger('').hasHandlers():
logging.getLogger('').handlers.clear()

# Se añaden dos nuevos handlers al root logger, uno pa


ra los niveles de debug o
# superiores y otro para que se muestre por pantalla l
os niveles de info o
# superiores.
file_debug_handler = logging.FileHandler('logs_debug.l
og')
file_debug_handler.setLevel(logging.DEBUG)
file_debug_format = logging.Formatter('%(asctime)-5s
%(name)-15s %(levelname)-8s %(message)s')
file_debug_handler.setFormatter(file_debug_format)
logging.getLogger('').addHandler(file_debug_handler)

consola_handler = logging.StreamHandler()
consola_handler.setLevel(logging.INFO)
consola_handler_format = logging.Formatter('%(asctim
e)-5s %(name)-15s %(levelname)-8s %(message)s')
consola_handler.setFormatter(consola_handler_format)
logging.getLogger('').addHandler(consola_handler)

# ======================= MAIN SCRIPT ================


============================
logging.debug('Inicio main script')
logging.info('Inicio main script')

suma(1,3)

logging.debug('Fin main script')


logging.info('Fin main script')

logging.shutdown()

2020-10-26 10:40:49,426 root INFO Inicio m


ain script
2020-10-26 10:40:49,426 root INFO función
suma ejecutada
2020-10-26 10:40:49,427 root INFO Fin main
script

Opción 2: Utilizar el logger root creado en


el main script y logger hijos en el resto de
scripts

Esta forma tiene las mismas ventajas que el anterior ejemplo pero,
además, permite saber de qué script procede cada log.
Tabla de contenidos In [23]: # El contenido del archivo funcion_suma_1.py es:
 
#import logging
Introducción
#logger = logging.getLogger("").getChild(__name__)
 Logging dentro de un único script
Salida por consola
#def suma(a,b):
Salida por fichero # if not isinstance(a, (int, float)) \
Salida por consola y varios fichero # or not isinstance(b, (int, float)):
 Logging entre varios scripts # raise Exception(
Opción 1: Utilizar solo el logger root del main
# scri logger.error("a y b deben ser números")
Opción 2: Utilizar el logger root creado en el#main )
Información de sesión # logger.info('función suma ejecutada')
# return(a+b)

In [24]: # ======================= MAIN SCRIPT ================


============================

import logging
from funcion_suma_1 import suma # Esta función tiene s
us propios logs

# Definición del logger root


#
------------------------------------------------------
-----------------------
logging.basicConfig(
format = '%(asctime)-5s %(name)-15s %(levelname)-8
s %(message)s',
level = logging.INFO,
filemode = "a"
)

# Nuevos handlers
#
------------------------------------------------------
-----------------------
# Si el root logger ya tiene handlers, se eliminan ant
es de añadir los nuevos.
# Esto es importante para que los logs no empiezen a d
uplicarse.
if logging.getLogger('').hasHandlers():
logging.getLogger('').handlers.clear()

# Se añaden dos nuevos handlers al root logger, uno pa


ra los niveles de debug o
# superiores y otro para que se muestre por pantalla l
os niveles de info o
# superiores.
file_debug_handler = logging.FileHandler('logs_debug.l
og')
file_debug_handler.setLevel(logging.DEBUG)
file_debug_format = logging.Formatter('%(asctime)-5s
%(name)-15s %(levelname)-8s %(message)s')
file_debug_handler.setFormatter(file_debug_format)
logging.getLogger('').addHandler(file_debug_handler)

consola_handler = logging.StreamHandler()
consola_handler.setLevel(logging.INFO)
consola_handler_format = logging.Formatter('%(asctim
e)-5s %(name)-15s %(levelname)-8s %(message)s')
consola_handler.setFormatter(consola_handler_format)
logging.getLogger('').addHandler(consola_handler)

logging.debug('Inicio main script')


logging.info('Inicio main script')

suma(1,3)

logging.debug('Fin main script')


logging.info('Fin main script')

logging.shutdown()

2020-10-26 10:40:49,439 root INFO Inicio m


ain script
2020-10-26 10:40:49,439 funcion_suma_1 INFO función
suma ejecutada
2020-10-26 10:40:49,440 root INFO Fin main
script
Tabla de contenidos
 
Introducción
Información de sesión
 Logging dentro de un único script
Salida por consola
Salida por fichero In [25]: from sinfo import sinfo
Salida por consola y varios fichero sinfo()
 Logging entre varios scripts -----
Opción 1: Utilizar solo el logger root del main scri
funcion_suma_1 NA
Opción 2: Utilizar el logger root creado en elnumpy
main 1.19.2
Información de sesión sinfo 0.3.1
-----
IPython 7.18.1
jupyter_client 6.1.2
jupyter_core 4.6.3
jupyterlab 2.1.3
notebook 6.0.3
-----
Python 3.8.6 (default, Oct 10 2020, 07:54:55) [GCC 5.4.0
20160609]
Linux-5.4.0-1028-aws-x86_64-with-glibc2.2.5
8 logical CPU cores, x86_64
-----
Session information updated at 2020-10-26 10:40

También podría gustarte