Chciałbym użyć dictConfig , ale dokumentacja jest trochę abstrakcyjna. Gdzie mogę znaleźć konkretny przykład słownika używanego z możliwością kopiowania i wklejania dictConfig?
Chciałbym użyć dictConfig , ale dokumentacja jest trochę abstrakcyjna. Gdzie mogę znaleźć konkretny przykład słownika używanego z możliwością kopiowania i wklejania dictConfig?
Odpowiedzi:
A może tutaj!
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
},
}
}
Stosowanie:
# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)
# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")
Jeśli widzisz zbyt wiele dzienników z pakietów innych firm, pamiętaj, aby uruchomić tę konfigurację przy użyciu logging.config.dictConfig(LOGGING_CONFIG) przed zaimportowaniem pakietów innych firm.
Źródła: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema
'disable_existing_loggers': Falseponieważ wtedy być może nie konfigurujesz go w całości, ale może ponownie używasz czegoś, co już tam jest True.
formatod formatters?
Przyjęta odpowiedź jest miła! Ale co by było, gdyby można było zacząć od czegoś mniej złożonego? Moduł logowania to bardzo potężna rzecz, a dokumentacja jest nieco przytłaczająca, szczególnie dla początkujących. Ale na początku nie musisz konfigurować elementów formatujących i programów obsługi. Możesz go dodać, kiedy dowiesz się, czego chcesz.
Na przykład:
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')który sprawił, że wszystko się u mnie zaskoczyło. Zamieszanie w dokumentacji polega na tym, że dzięki dictConfig nie musimy już wykonywać getLoggerani żadnej z tych czynności.
'': { 'level': 'INFO'...i dlaczego nie działa bez niego (np. przy zmianie pustej wartości na prawidłową wartość, na przykładstandard
getLogger()jeśli chcesz mieć wiele rejestratorów o różnych nazwach. Każdy z tych programów rejestrujących dziedziczy konfigurację z głównego programu rejestrującego.
getLoggerjest zawsze opcjonalne. Używając tej logging.info()metody bezpośrednio, używany jest główny rejestrator, podczas gdy getLogger()możesz mieć różne rejestratory, z różnymi nazwami i poziomami.
Przykład z obsługą strumienia, programem obsługi plików, obrotowym programem obsługi plików i programem obsługi SMTP
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)
Znalazłem domyślną konfigurację Django v1.11.15 poniżej, mam nadzieję, że to pomoże
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
rootloggera: na najwyższym poziomie słownika. Jest to opisane w dokumentach , ma pierwszeństwo przed sytuacją ,['loggers']['']gdy oba są obecne, ale moim zdaniem['loggers']['']jest bardziej logiczne. Zobacz także dyskusję tutaj