Ведення журналу налаштувань Django за замовчуванням


94

Здається, я не можу зрозуміти, як налаштувати реєстратор "за замовчуванням" для моєї інсталяції Django. Я хотів би використовувати нову LOGGINGнастройку Django 1.3 у settings.py.

Я розглянув приклад Django Logging Doc , але мені здається, що вони встановлюють лише обробники, які здійснюватимуть реєстрацію для певних реєстраторів. У випадку їх прикладу вони встановлюють обробник для реєстраторів з іменами 'django', 'django.request' та 'myproject.custom'.

Все, що я хочу зробити, це встановити за замовчуванням, logging.handlers.RotatingFileHandlerяке за замовчуванням буде обробляти всі реєстратори. тобто, якщо я створюю новий модуль десь у своєму проекті, і він позначається приблизно так:, 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`!

Відповіді:


153

Зрозумів це ...

Ви можете встановити «все» логгер з допомогою посилання його з нового рядка: ''.

Як приклад, у наступному налаштуванні у мене зберігаються всі події журналу logs/mylog.log, за винятком django.requestподій журналу, які будуть збережені logs/django_request.log. Тому що 'propagate'встановлено на Falseмій django.requestреєстратор, то журнал події ніколи не досягнуть в «всіх» журналирования.

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
Кріс, документи Django щодо цього не бентежать. Дякую за це

5
Крихітна корекція: коментар передбачає, що на реєстрацію sql вплине реєстратор django.request. Щоб перенаправити ведення журналу sql, слід визначити реєстратор для 'django.db'. Реєстратор django.request обробляє 5xx та 4xx http-відповіді.
rych

У цьому допомагає інший користувач, такий як я: реєстратор створюватиме файли журналів, але спочатку потрібно створити logs/папку :-). В іншому випадку ви отримаєте повідомлення про помилку під час запуску ./manange.py runserver. @Chris W. Дякую за приклади налаштувань ведення журналу. Мені це дуже допомогло!
hobbes3

3
@arindamroychowdhury При вищевказаної конфігурації , якщо ви робите logger = logging.getLogger('foo'); logger.warn('bar');те defaultобробник буде ловити , що протоколювання і що - щось на зразок <time> WARN: foo: barбуде в кінцевому підсумку вlogs/mylog.log
Chris W.

8
Дякую, здається, що це '' означає кореневий реєстратор. Цю корисну інформацію не було знайдено в документації Django.
Eino Mäkitalo 12.03.13

25

Як ви вже сказали у своїй відповіді , Кріс, одним із варіантів визначення реєстратора за замовчуванням є використання порожнього рядка як його ключа.

Однак я думаю, що передбачуваним способом є визначення спеціального реєстратора під 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' є дещо логічним, я все одно вважаю їх дещо непослідовним переміщати rootзапис у корінь dict в процесі інакшого плавного переходу від логіки 2.6 fileConfig до 2.7 dictConfig.
Antony Hatchkins

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

0

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

Сподіваюся, це допоможе іншим, кого, як і мене, бентежили 2 різні способи налаштування кореневого реєстратора.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.