Python - Как сбросить лог? (Django)
Я работаю с Django-nonrel на Google App Engine, что вынуждает меня использовать logging.debug()
вместо print()
.
Модуль "logging" предоставляется Django, но у меня возникают трудности с его использованием вместо print()
.
Например, если мне нужно проверить содержимое переменной x, я пишу:
logging.debug('x is: %s' % x)
. Но если программа выдает ошибку сразу после этого (не успевая записать данные в поток), то это сообщение никогда не отображается.
Таким образом, для отладки мне нужно, чтобы debug()
записывался в лог до завершения программы в случае ошибки, но этого не происходит.
5 ответ(ов)
Я думаю, это может сработать для вас, если вы используете только один (или стандартный) обработчик:
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
Кроме того, это может сказаться на производительности, но если вы действительно находитесь в затруднительном положении, это может помочь в отладке.
В 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]
В Python 3.8 функция logging.shutdown()
используется для завершения работы системы логирования. Это необходимо, когда вы хотите убедиться, что все обработчики логов завершили свою работу и освободили ресурсы, которые они использовали.
Вот краткий пример использования:
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO)
# Логирование сообщения
logging.info("Это информационное сообщение.")
# Завершение работы системы логирования
logging.shutdown()
Когда вы вызываете logging.shutdown()
, все активные обработчики логов выполняют свою завершительную работу, например, записывают оставшиеся сообщения в файл или освобождают любые другие ресурсы, которые они могли занять. Это полезно, когда приложение завершает свою работу, чтобы гарантировать, что все сообщения были обработаны.
Учтите, что вызывая logging.shutdown()
, вы больше не сможете использовать систему логирования в текущем процессе, если только вы не инициализируете её заново.
Для получения дополнительной информации вы можете обратиться к документации Python.
У меня была такая же проблема, когда я хотел, чтобы log.info
выводился в stdout
. Оказалось, что мне просто нужно было добавить обработчик потока для stdout, и это решает задачу.
logger.addHandler(logging.StreamHandler(sys.stdout))
Также не забудьте установить правильный уровень логирования, но это очевидно.
Возможно, проблема с логированием (которое, кажется, не срабатывает) возникает из-за того, что в потоке происходит исключение. Поток должен самостоятельно обрабатывать свои исключения и логировать их.
Не стоит полагаться на основной поток для перехвата и логирования исключений из потоков.
Например, таймер, который периодически запускает функцию, будет вести себя именно так, и эта функция должна самостоятельно обрабатывать и логировать свои исключения.
'pip' не распознан как командa внутреннего или внешнего формата
Как окрасить вывод логирования Python?
Как выполнить поиск в стиле getattr() в шаблоне Django
Как разобрать неправильный JSON с помощью Python?
PIL / JPEG библиотека: "декодировщик JPEG недоступен"