Apuntes_Python/02_conceptos/10_logging
2024-01-16 12:23:41 -03:00
..
a_basico.py init Apuntes Python 2022-12-24 22:41:20 -03:00
b_personalizado.py init Apuntes Python 2022-12-24 22:41:20 -03:00
c_config_log_file.py init Apuntes Python 2022-12-24 22:41:20 -03:00
d_captura_stack_traces.py init Apuntes Python 2022-12-24 22:41:20 -03:00
e_rotating_file_handler.py init Apuntes Python 2022-12-24 22:41:20 -03:00
f_timed_rotating_file_handler.py init Apuntes Python 2022-12-24 22:41:20 -03:00
file.log init Apuntes Python 2022-12-24 22:41:20 -03:00
logging.conf init Apuntes Python 2022-12-24 22:41:20 -03:00
README.md ed: domain links on files <kickto.net >letz.dev 2024-01-16 12:23:41 -03:00

Logging

Python tiene integrado un poderoso módulo de registros o logging. import logging

HOW TO

Niveles de registros:

  • debug
  • info
  • warning
  • error
  • critical

Solo se muestran en pantalla (consola) los warning, error y critical.

Estos se pueden configurar

    logging.basicConfig(leve=logging.******, format='******', datefmt='******')

Es buena practica crear loggers propios (ej. helper.py)

Jerarquia de loggers
Manejadores de loggers

Metodos de configuracion de loggers:

Ejemplos:


Logger personalizado

import logging

logger = logging.getLogger(__name__)
# logger.propagate = False

# Crear manejador
stream_h = logging.StreamHandler()
file_h = logging.FileHandler('file.log')
# Nivel y formato
stream_h.setLevel(logging.WARNING)
file_h.setLevel(logging.ERROR)

formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
stream_h.setFormatter(formatter)
file_h.setFormatter(formatter)

# Agregar manejadores a logger
logger.addHandler(stream_h)
logger.addHandler(file_h)

logger.info('Hola desde el modulo helper')
logger.warning('Esta es una advertencia')
logger.error('Este es un msj de error')

Registro de eventos/sucesos (logging)

import logging

# Configuración de logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    datefmt='%d/%m/%Y %H:%M:%S')

logging.debug("Este es un mensaje 'debugeo'")
logging.info("Este es un mensaje de informacion")
logging.warning("Este es un mensaje de advertencia")
logging.error("Este es un mensaje de error")
logging.critical("Este es un mensaje de error critico")
"""
04/04/2021 17:57:27 - root - DEBUG - Este es un mensaje 'debugeo'
04/04/2021 17:57:27 - root - INFO - Este es un mensaje de informacion
04/04/2021 17:57:27 - root - WARNING - Este es un mensaje de advertencia
04/04/2021 17:57:27 - root - ERROR - Este es un mensaje de error
04/04/2021 17:57:27 - root - CRITICAL - Este es un mensaje de error critico
"""

import helper
# 04/04/2021 18:12:48 - helper - INFO - Hola desde el modulo helper

Logging con archivo de configuración

import logging.config

logging.config.fileConfig('logging.conf')

logger = logging.getLogger('ejemploSimple')
logger.debug('este es un mensaje de DEBUG')

./logging.conf

[loggers]
keys=root, ejemploSimple

[handlers]
keys=handlerConsola

[formatters]
keys=formatterSimple

[logger_root]
level=DEBUG
handlers=handlerConsola

[logger_ejemploSimple]
level=DEBUG
handlers=handlerConsola
qualname=ejemploSimple
propagate=0

[handler_handlerConsola]
class=StreamHandler
level=DEBUG
formatter=formatterSimple
args=(sys.stdout,)

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

Captura de stack traces

import logging

print('Captura de error:\n')
try:
    a = [1,2,3]
    val = a[4]
except IndexError as e:
    logging.error(e)

print('\n\nCaptura de error mas seguimiento:\n')
try:
    a = [1,2,3]
    val = a[4]
except IndexError as e:
    logging.error(e, exc_info=True)


print('\n\nCaptura de error desconocido y seguimiento:\n')
import traceback
try:
    a = [1,2,3]
    val = a[4]
except:
    logging.error('El error es %s', traceback.format_exc())

RotatingFileHandler

Mantiene un log con los eventos mas actuales y mantiene el log de un tamaño mas pequeño.

import logging
from logging.handlers import RotatingFileHandler

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Sobreescribe el log cuando este pasa los 2KB, y mantiene respaldo de los logs.
# app.log.1, app.log.2, etc.
handler = RotatingFileHandler(
                './rotating_logs/rotating_file_handler_app.log',
                maxBytes=2000, backupCount=5
                )
logger.addHandler(handler)

for _ in range(10000):
    logger.info('manejador de logs rotativo')

./rotating_logs/

📂️ rotating_logs
├── 📄️ rotating_file_handler_app.log
├── 📄️ rotating_file_handler_app.log.1
├── 📄️ rotating_file_handler_app.log.2
├── 📄️ rotating_file_handler_app.log.3
├── 📄️ rotating_file_handler_app.log.4
└── 📄️ rotating_file_handler_app.log.5

TimedRotatingFileHandler

Mantiene un log con los eventos mas actuales y mantiene el log en
un tamaño mas pequeño. Basado en tiempo.

import logging
import time
from logging.handlers import TimedRotatingFileHandler

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Sobreescribe el log despues de cierto intervalo, mantiene respaldos
# especificadso en backupCount.
# (s)egundos, (m)inutos, (h)oras, (d)ias, midnight, (w0)lunes, (w1)martes, (w3)....
handler = TimedRotatingFileHandler(
                './rotating_logs/timed_rotating_file_handler_app.log',
                when='s', 
                interval=3, 
                backupCount=4
                )
logger.addHandler(handler)

for _ in range(25):
    logger.info('manejador de logs rotativo temporizado')
    time.sleep(1)
helper - ERROR - Este es un msj de error
helper - ERROR - Este es un msj de error
helper - ERROR - Este es un msj de error
helper - ERROR - Este es un msj de error

./rotating_logs/

📂️ rotating_logs
├── 📄️ timed_rotating_file_handler_app.log
├── 📄️ timed_rotating_file_handler_app.log.2021-05-06_17-20-58
├── 📄️ timed_rotating_file_handler_app.log.2021-05-06_17-21-01
├── 📄️ timed_rotating_file_handler_app.log.2021-05-06_17-21-04
└── 📄️ timed_rotating_file_handler_app.log.2021-05-06_17-21-07