Настройка записи по умолчанию в Django

Я не могу понять, как настроить регистратор по умолчанию для моей установки 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'!

Ответ 1

Выяснил это...

Вы устанавливаете логгер "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
        },
    }
}

Ответ 2

Как вы сказали в своем ответе, Крис, один из вариантов определения регистратора по умолчанию - использовать пустую строку в качестве ключа.

Тем не менее, я думаю, что предполагаемый способ - определить специальный регистратор под 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' переопределяет '' если вы определяете оба, только потому, что корневая запись обрабатывается последней.

Ответ 3

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',

Ответ 4

Я сделал быстрый пример, чтобы проверить, какая конфигурация используется, когда в 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) ссылались на один и тот же экземпляр регистратора, корневой регистратор.

Надеюсь, что это поможет другим, которых, как и я, смутили два разных способа настройки корневого регистратора.