Django Setup Default Logging

Parece que no puedo averiguar cómo configurar un registrador “predeterminado” para mi instalación de Django. Me gustaría usar la nueva configuración de LOGGING Django 1.3 en settings.py .

He mirado el ejemplo del Django Logging Doc , pero me parece que solo configuran controladores que harán el registro de registradores en particular. En el caso de su ejemplo, configuraron el controlador para los registradores llamados ‘django‘, ‘django.request’ y ‘myproject.custom’.

Todo lo que quiero hacer es configurar un logging.handlers.RotatingFileHandler predeterminado que manejará todos los registradores de forma predeterminada. es decir, si hago un nuevo módulo en algún lugar de mi proyecto y se denota con algo como: my_app_name.my_new_module , debería poder hacer esto y hacer que todos los registros pasen a los registros de archivos giratorios.

 # In file './my_app_name/my_new_module.py' import logging logger = logging.getLogger('my_app_name.my_new_module') logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`! 

Lo averigué…

Usted establece el registrador ‘catch all’ haciendo referencia a él con la cadena vacía: '' .

Como ejemplo, en la siguiente configuración tengo todos los eventos de registro guardados en logs/mylog.log , con la excepción de los eventos de registro django.request que se guardarán en logs/django_request.log . Debido a que 'propagate' está establecido en False para mi registrador django.request , el evento log nunca alcanzará el registrador ‘catch all’.

 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, }, 'handlers': { 'default': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': 'logs/mylog.log', 'maxBytes': 1024*1024*5, # 5 MB 'backupCount': 5, 'formatter':'standard', }, 'request_handler': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': 'logs/django_request.log', 'maxBytes': 1024*1024*5, # 5 MB 'backupCount': 5, 'formatter':'standard', }, }, 'loggers': { '': { 'handlers': ['default'], 'level': 'DEBUG', 'propagate': True }, 'django.request': { 'handlers': ['request_handler'], 'level': 'DEBUG', 'propagate': False }, } } 

Como dijiste en tu respuesta , Chris, una opción para definir un registrador predeterminado es usar la cadena vacía como su clave.

Sin embargo, creo que la forma prevista es definir un registrador especial en la clave root del diccionario de configuración de registro. Encontré esto en la documentación de Python :

raíz : esta será la configuración del registrador raíz. El procesamiento de la configuración será como para cualquier registrador, excepto que la configuración de propagate no será aplicable.

Aquí está la configuración de su respuesta modificada para usar la clave root :

 LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, }, 'handlers': { 'default': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': 'logs/mylog.log', 'maxBytes': 1024*1024*5, # 5 MB 'backupCount': 5, 'formatter':'standard', }, 'request_handler': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': 'logs/django_request.log', 'maxBytes': 1024*1024*5, # 5 MB 'backupCount': 5, 'formatter':'standard', }, }, 'root': { 'handlers': ['default'], 'level': 'DEBUG' }, 'loggers': { 'django.request': { 'handlers': ['request_handler'], 'level': 'DEBUG', 'propagate': False }, } } 

Para ser justos, no veo ninguna diferencia en el comportamiento entre las dos configuraciones. Parece que la definición de un registrador con una clave de cadena vacía modificará el registrador raíz, porque logging.getLogger('') devolverá el registrador raíz.

La única razón por la que prefiero 'root' over '' es que es explícito sobre la modificación del root logger. En caso de que tuvieras curiosidad, 'root' reemplaza '' si defines ambas, solo porque la entrada de la raíz se procesa en último lugar.

 import logging logger = logging.getLogger(__name__) 

después de añadir:

 logging.basicConfig( level = logging.DEBUG, format = '%(name)s %(levelname)s %(message)s', ) 

podemos cambiar el formato a:

 format = '"%(levelname)s:%(name)s:%(message)s" ', 

o

 format = '%(name)s %(asctime)s %(levelname)s %(message)s', 

Hice una muestra rápida para verificar qué configuración se usa cuando se hace referencia tanto a root clave root como al registrador vacío en config dict.

 import logging.config LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'fmt1': { 'format': '[FMT1] %(asctime)-15s %(message)s', }, 'fmt2': { 'format': '[FMT2] %(asctime)-15s %(message)s', } }, 'handlers': { 'console1': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'fmt1', }, 'console2': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'fmt2', }, }, # First config for root logger: console1 -> fmt1 'root': { 'handlers': ['console1'], 'level': 'DEBUG', 'propagate': True, }, 'loggers': { # Second config for root logger: console2 -> fmt2 '': { 'handlers': ['console2'], 'level': 'DEBUG', 'propagate': True, }, }, } logging.config.dictConfig(LOGGING) l1 = logging.getLogger() l2 = logging.getLogger('') root = logging.root l1.info("l1") l2.info("l2") root.info("root logger") 

Imprime el siguiente resultado:

 [FMT1] 2018-12-18 17:24:47,691 l1 [FMT1] 2018-12-18 17:24:47,691 l2 [FMT1] 2018-12-18 17:24:47,691 root logger 

lo que indica que la configuración en clave de root tiene la máxima prioridad. Si se elimina el bloque, el resultado es:

 [FMT2] 2018-12-18 17:25:43,757 l1 [FMT2] 2018-12-18 17:25:43,757 l2 [FMT2] 2018-12-18 17:25:43,757 root logger 

En ambos casos, pude depurar y determinar que los tres registradores ( l1 , l2 y root ) l2 referencia a la misma instancia del registrador, el registrador raíz.

Espero que ayude a otros que, como yo, estaban confundidos por las 2 formas diferentes de configurar el registrador raíz.