# Logging Python tiene integrado un poderoso módulo de registros o [logging](https://docs.python.org/es/3/library/logging.html). `import logging` [HOW TO](https://docs.python.org/es/3/howto/logging.html) 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: - **logging.conf** (c_config_log_file.py) - [dictConfig](https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig) - captura stack traces - rotating file - timed rotating file - logs JSON [python-json-logger](https://github.com/madzak/python-json-logger) Ejemplos: - [Logger personalizado](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#logger-personalizado) - [Registro de eventos/sucesos (logging)](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#registro-de-eventos-sucesos-logging) - [Logging con archivo de configuración](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#registro-de-eventos-sucesos-logging) - [Captura de stack traces](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#captura-de-stack-traces) - [RotatingFileHandler](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#captura-de-stack-traces) - [TimedRotatingFileHandler](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/10_logging#timedrotatingfilehandler) ----- ## Logger personalizado ```python 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) ```python 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 ```python 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 ```python 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. ```python 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. ```python 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 ```