Настройки логов для django
Рассмотрим дефолтные настройки логов в django и попробуем их сделать максимально удобными.
Вот что есть в settings.py после команды django-admin.py startproject project_name
(django 1.5):
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
Как и написано в коментарии, здесь определяется логгер, который будет отсылать сообщения на email всем админам при возникновении ошибки HTTP 500 (по сути это любое неперехваченное исключение - exception), при условии, что settings.DEBUG = False
. Список email’ов определен в settings.ADMINS
.
Однако, это не все. Есть еще дефолтные настройки, они определены в django.utils.log.DEFAULT_LOGGING
. Так они выглядят для версии 1.5.4 (актуальную версию можно посмотреть на github):
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console':{
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'null': {
'class': 'django.utils.log.NullHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console'],
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'py.warnings': {
'handlers': ['console'],
},
}
}
Что они означают?
Логгер ‘django’ пишет все логи с дочерних логгеров в консоль с уровнем сообщений WARNING и выше (‘level’ для логгера ‘django’ не задан, а по умолчанию он равен WARNING). Дочерние логгеры такие: ‘django.db.backends’, ‘django.contrib.gis’ и т.д. Но кроме ‘django.request’, у которого стоит ‘propagate’: False.
Логгер ‘py.warnings’ так же пишет сообщения от модуля warnings в консоль. Например DeprecationWarnings.
Пример удобного (на мой взгляд) конфига
Для простоты можно определить один корневой логгер, который будет собирать все сообщения со всех модулей. Если settings.DEBUG = True
, то он будет писать в консоль и в специальный отладочный лог-файл все сообщения. Если же settings.DEBUG = False
, то сообщения будут писаться только в продакшн лог-файл, только с уровнем INFO и выше.
При settings.DEBUG = True
будут выводиться в консоль и писаться в лог-файл все SQL запросы, что очень удобно. При желании можно создать отдельный логгер ‘django.db’ с ‘propagate’: False и задать ему нужные настройки.
Т.к. тут я определил корневой логгер, остальным логгерам ставлю null handler, чтобы сообщения не дублировались.
Код на gist.github
Настройки будут работать для django 1.5+
Для более ранних версий django можно создать файл log.py:
import logging
from django.conf import settings
try:
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
class RequireDebugTrue(logging.Filter):
def filter(self, record):
return settings.DEBUG
class RequireDebugFalse(logging.Filter):
def filter(self, record):
return not settings.DEBUG
И использовать пути для NullHandler
, RequireDebugTrue
, RequireDebugFalse
из этого файла, вместо django.utils.log. ...
.
Теперь, в любом файле можно сделать так:
import logging
logger = logging.getLogger(__name__)
logger.debug("some message")
logger.warning("oops, it is a warning")
logger.error("bad, very bad")
try:
# do something
except ValueError:
logger.exception("I know it could happen")
и все ваши логи попадут в нужное место, в зависимости от DEBUG.