0

Python - Как сбросить лог? (Django)

15

Я работаю с Django-nonrel на Google App Engine, что вынуждает меня использовать logging.debug() вместо print().

Модуль "logging" предоставляется Django, но у меня возникают трудности с его использованием вместо print().

Например, если мне нужно проверить содержимое переменной x, я пишу: logging.debug('x is: %s' % x). Но если программа выдает ошибку сразу после этого (не успевая записать данные в поток), то это сообщение никогда не отображается.

Таким образом, для отладки мне нужно, чтобы debug() записывался в лог до завершения программы в случае ошибки, но этого не происходит.

5 ответ(ов)

0

Я думаю, это может сработать для вас, если вы используете только один (или стандартный) обработчик:

import logging
logger = logging.getLogger()
logging.debug('wat wat')
logger.handlers[0].flush()

Тем не менее, в документации это не рекомендуется.

Код приложения не должен напрямую создавать и использовать экземпляры Handler. Вместо этого класс Handler является базовым классом, который определяет интерфейс, который должны иметь все обработчики, и устанавливает некоторые стандартные поведения, которые дочерние классы могут использовать (или переопределять). http://docs.python.org/2/howto/logging.html#handler-basic

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

0

В Django логирование основано на стандартном модуле логирования Python.

Этот модуль имеет метод на уровне модуля: logging.shutdown(), который завершает работу всех обработчиков и останавливает систему логирования (т.е. логирование больше не может быть использовано после его вызова).

Если изучить код этой функции, то можно увидеть, что в текущей версии (Python 2.7) модуль логирования хранит список слабых ссылок на всех обработчиков в переменной уровня модуля с именем _handlerList, поэтому все обработчики можно сбросить с помощью следующего кода:

[h_weak_ref().flush() for h_weak_ref in logging._handlerList]

Поскольку это решение использует внутренности модуля, более предпочтительным является решение от @Mikes, однако оно зависит от наличия доступа к логгеру. Это можно обобщить следующим образом:

[h.flush() for h in my_logger.handlerList]
0

В Python 3.8 функция logging.shutdown() используется для завершения работы системы логирования. Это необходимо, когда вы хотите убедиться, что все обработчики логов завершили свою работу и освободили ресурсы, которые они использовали.

Вот краткий пример использования:

import logging

# Настройка логирования
logging.basicConfig(level=logging.INFO)

# Логирование сообщения
logging.info("Это информационное сообщение.")

# Завершение работы системы логирования
logging.shutdown()

Когда вы вызываете logging.shutdown(), все активные обработчики логов выполняют свою завершительную работу, например, записывают оставшиеся сообщения в файл или освобождают любые другие ресурсы, которые они могли занять. Это полезно, когда приложение завершает свою работу, чтобы гарантировать, что все сообщения были обработаны.

Учтите, что вызывая logging.shutdown(), вы больше не сможете использовать систему логирования в текущем процессе, если только вы не инициализируете её заново.

Для получения дополнительной информации вы можете обратиться к документации Python.

0

У меня была такая же проблема, когда я хотел, чтобы log.info выводился в stdout. Оказалось, что мне просто нужно было добавить обработчик потока для stdout, и это решает задачу.

logger.addHandler(logging.StreamHandler(sys.stdout))

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

0

Возможно, проблема с логированием (которое, кажется, не срабатывает) возникает из-за того, что в потоке происходит исключение. Поток должен самостоятельно обрабатывать свои исключения и логировать их.

Не стоит полагаться на основной поток для перехвата и логирования исключений из потоков.

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь