J'aimerais utiliser dictConfig , mais la documentation est un peu abstraite. Où puis-je trouver un exemple concret, copiable et collable du dictionnaire utilisé avec dictConfig
?
J'aimerais utiliser dictConfig , mais la documentation est un peu abstraite. Où puis-je trouver un exemple concret, copiable et collable du dictionnaire utilisé avec dictConfig
?
Réponses:
Et ici!
LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default': {
'level': 'INFO',
'formatter': 'standard',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout', # Default is stderr
},
},
'loggers': {
'': { # root logger
'handlers': ['default'],
'level': 'WARNING',
'propagate': False
},
'my.packg': {
'handlers': ['default'],
'level': 'INFO',
'propagate': False
},
'__main__': { # if __name__ == '__main__'
'handlers': ['default'],
'level': 'DEBUG',
'propagate': False
},
}
}
Usage:
# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)
# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")
Si vous voyez trop de journaux de packages tiers, assurez-vous d'exécuter cette configuration en utilisant logging.config.dictConfig(LOGGING_CONFIG)
avant que les packages tiers ne soient importés.
Référence: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema
'disable_existing_loggers': False
as alors vous ne configurez peut-être pas tout le tissu, mais peut-être en réutilisant quelque chose qui est déjà là. Si vous le réglez, True
je ne semble pas obtenir de sortie.
format
partir de formatters
?
La réponse acceptée est gentille! Mais que se passerait-il si l'on pouvait commencer par quelque chose de moins complexe? Le module de journalisation est une chose très puissante et la documentation est un peu écrasante, surtout pour les novices. Mais pour le début, vous n'avez pas besoin de configurer les formateurs et les gestionnaires. Vous pouvez l'ajouter lorsque vous déterminez ce que vous voulez.
Par exemple:
import logging.config
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'loggers': {
'': {
'level': 'INFO',
},
'another.module': {
'level': 'DEBUG',
},
}
}
logging.config.dictConfig(DEFAULT_LOGGING)
logging.info('Hello, log')
logging.info('Hello, log')
qui a fait claquer les choses pour moi. La confusion dans la documentation est qu'avec dictConfig, nous n'avons plus besoin d'effectuer getLogger
ou l'une de ces actions.
'': { 'level': 'INFO'...
et pourquoi elle ne fonctionne pas sans elle (par exemple, lors de la modification de la valeur vide en une valeur valide telle questandard
getLogger()
si vous voulez plusieurs enregistreurs avec des noms différents. Chacun de ces enregistreurs hérite de la configuration de l'enregistreur racine.
getLogger
est toujours facultatif. Lorsque vous utilisez la logging.info()
méthode directement, l'enregistreur racine est utilisé, tandis qu'avec getLogger()
vous pouvez avoir différents enregistreurs, avec des noms et des niveaux différents.
Exemple avec Stream Handler, File Handler, Rotating File Handler et SMTP Handler
from logging.config import dictConfig
LOGGING_CONFIG = {
'version': 1,
'loggers': {
'': { # root logger
'level': 'NOTSET',
'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
},
'my.package': {
'level': 'WARNING',
'propagate': False,
'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
},
},
'handlers': {
'debug_console_handler': {
'level': 'DEBUG',
'formatter': 'info',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
},
'info_rotating_file_handler': {
'level': 'INFO',
'formatter': 'info',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'info.log',
'mode': 'a',
'maxBytes': 1048576,
'backupCount': 10
},
'error_file_handler': {
'level': 'WARNING',
'formatter': 'error',
'class': 'logging.FileHandler',
'filename': 'error.log',
'mode': 'a',
},
'critical_mail_handler': {
'level': 'CRITICAL',
'formatter': 'error',
'class': 'logging.handlers.SMTPHandler',
'mailhost' : 'localhost',
'fromaddr': 'monitoring@domain.com',
'toaddrs': ['dev@domain.com', 'qa@domain.com'],
'subject': 'Critical error with application name'
}
},
'formatters': {
'info': {
'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
},
'error': {
'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
},
},
}
dictConfig(LOGGING_CONFIG)
J'ai trouvé la configuration par défaut de Django v1.11.15 ci-dessous, j'espère que cela aide
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'django.server': {
'()': 'django.utils.log.ServerFormatter',
'format': '[%(server_time)s] %(message)s',
}
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
},
'django.server': {
'handlers': ['django.server'],
'level': 'INFO',
'propagate': False,
},
}
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.handlers
from logging.config import dictConfig
logger = logging.getLogger(__name__)
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
}
def configure_logging(logfile_path):
"""
Initialize logging defaults for Project.
:param logfile_path: logfile used to the logfile
:type logfile_path: string
This function does:
- Assign INFO and DEBUG level to logger file handler and console handler
"""
dictConfig(DEFAULT_LOGGING)
default_formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s():%(lineno)s] [PID:%(process)d TID:%(thread)d] %(message)s",
"%d/%m/%Y %H:%M:%S")
file_handler = logging.handlers.RotatingFileHandler(logfile_path, maxBytes=10485760,backupCount=300, encoding='utf-8')
file_handler.setLevel(logging.INFO)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(default_formatter)
console_handler.setFormatter(default_formatter)
logging.root.setLevel(logging.DEBUG)
logging.root.addHandler(file_handler)
logging.root.addHandler(console_handler)
[31/10/2015 22:00:33] [DEBUG] [yourmodulename] [yourfunction_name():9] [PID:61314 TID:140735248744448] this is logger infomation from hello module
root
enregistreur: au niveau supérieur du dictionnaire. Il est décrit dans la documentation , a la préférence sur le['loggers']['']
lorsque les deux sont présents, mais à mon avis,['loggers']['']
est plus logique. Voir aussi la discussion ici