248 lines
6.9 KiB
Markdown
248 lines
6.9 KiB
Markdown
# 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
|
|
```
|
|
|