Я не могу понять, как настроить регистратор по умолчанию для моей установки Django. Я хотел бы использовать новую настройку LOGGING
в Django 1.3 в settings.py
.
Я посмотрел на пример Django Logging Doc, но мне кажется, что они только устанавливают обработчики, которые будут вести журналы для определенных регистраторов. В случае их примера они устанавливают обработчик для регистраторов с именами 'django', 'django.request' и 'myproject.custom'.
Все, что я хочу сделать, это установить по умолчанию logging.handlers.RotatingFileHandler
который будет обрабатывать все регистраторы по умолчанию. то есть, если я my_app_name.my_new_module
новый модуль где-нибудь в моем проекте, и он обозначается чем-то вроде: my_app_name.my_new_module
, я должен быть в состоянии сделать это, и вся my_app_name.my_new_module
вращающегося файла.
# 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'!
Выяснил это...
Вы устанавливаете логгер "catch all", ссылаясь на него с пустой строкой: ''
.
В качестве примера, в следующей настройке, все события журнала сохраняются в logs/mylog.log
, за исключением django.request
событий журнала, которые будут сохранены в logs/django_request.log
. Поскольку 'propagate'
установлен на False
для моего регистратора django.request
, событие журнала никогда не достигнет регистратора "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
},
}
}
Как вы сказали в своем ответе, Крис, один из вариантов определения регистратора по умолчанию - использовать пустую строку в качестве ключа.
Тем не менее, я думаю, что предполагаемый способ - определить специальный регистратор под root
ключом словаря конфигурации журналирования. Я нашел это в документации по Python:
root - это будет конфигурация для корневого логгера. Обработка конфигурации будет такой же, как для любого регистратора, за исключением того, что параметр
propagate
не будет применяться.
Здесь конфигурация из вашего ответа была изменена для использования 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
},
}
}
Честно говоря, я не вижу никакой разницы в поведении между двумя конфигурациями. Похоже, что определение логгера с пустым строковым ключом изменит корневой логгер, потому что logging.getLogger('')
вернет корневой логгер.
Единственная причина, по которой я предпочитаю 'root'
''
заключается в том, что она явно касается изменения корневого регистратора. Если вам интересно, 'root'
переопределяет ''
если вы определяете оба, только потому, что корневая запись обрабатывается последней.
root
запись в корень dict в процессе плавного перехода от логики 2.6 fileConfig к логики 2.7 dictConfig.
Я сделал быстрый пример, чтобы проверить, какая конфигурация используется, когда в config dict упоминаются как root
ключ, так и пустой регистратор ''
.
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")
Печатает следующий результат:
[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
указывает, что конфигурация под root
ключом имеет самый высокий приоритет. Если блок удален, результат:
[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
В обоих случаях мне удалось отладить и определить, что все три регистратора (l1
, l2
и root
) ссылались на один и тот же экземпляр регистратора, корневой регистратор.
Надеюсь, что это поможет другим, которых, как и я, смутили два разных способа настройки корневого регистратора.
import logging
logger = logging.getLogger(__name__)
после добавления:
logging.basicConfig(
level = logging.DEBUG,
format = '%(name)s %(levelname)s %(message)s',
)
мы можем изменить формат:
format = '"%(levelname)s:%(name)s:%(message)s" ',
или
format = '%(name)s %(asctime)s %(levelname)s %(message)s',