Подтвердить что ты не робот

Запись в Python. Есть ли что-то ниже DEBUG?

В некоторых других технологиях мы иногда использовали уровень журнала ниже DEBUG, который, как мне кажется, назывался "verbose". Я понимаю, что потребность в таком уровне очень субъективна. Но, на мой взгляд, "просто" с INFO и DEBUG на самом деле недостаточно. У нас были времена, когда нужно было регистрировать что-то очень спаммое (больше спама, чем отладка). На практике мы производим сборки без этого включения, но в некоторых случаях мы включили бы этот уровень регистрации после того, как продукт был установлен на некоторые настройки QA, отслеживая ошибку и т.д.

Есть ли способ (легко или иначе) регистрировать что-то ниже уровня DEBUG, используя стандартную библиотеку протоколов python?

В файле temp.py я могу сделать следующее:

logging.addLevelName(5,"verbose")
VERBOSE = 5

logger = logging.getLogger("foo")
logger.setLevel(VERBOSE)
logger.log(VERBOSE,"blah!")

Это работает, когда я запускаю temp.py в моей среде IDE (и журналы на stdout), но наши настоящие демоны используют стандартный синтаксис конфигурации файла/словаря для настройки ведения журнала, и я не вижу никакого способа указать, что уровень 5 должен быть используется для демона.

Я преследую то, что не реально выполнимо?

Для тех, кто может задаться вопросом, почему мне нужно что-то меньшее, чем DEBUG, это для случайного типа ведения журнала, который может возникать очень часто (возможно, внутренний цикл), который я обычно не хотел бы видеть даже в DEBUG, но в какой-то производственной системе было бы полезно включить его через некоторое время, не требуя добавления дополнительных записей в исходный код и повторного развертывания и т.д.

EDIT1 - Очевидно, что библиотека протоколирования позволяет настраивать уровни. Поскольку DEBUG - это уровень 10, есть место где-то в диапазоне 1..9. Если я определяю настраиваемый уровень (например, в примере кода выше), я думаю, что мой реальный вопрос заключается в том, как включить этот уровень ведения журнала из файла конфигурации журнала json?

EDIT2 - Следующее будет работать, если бы не тот факт, что нам нужны/использовать файлы конфигурации json (требование, которое я не могу изменить):

import logging

logging.basicConfig(filename='example.log',level=5)
VERBOSE = 5
logging.addLevelName(5,"verbose")
logger = logging.getLogger("bar")
logger.log(VERBOSE,"blah!")

РЕДАКТИРОВАТЬ 3 - Выяснил это... Вызов

logging.addLevelName(5,"VERBOSE")

является критическим. У меня просто не было этого в нужном месте. В моем случае мне просто нужно было сделать вышеупомянутый вызов перед вызовом в журнал протоколов dictConfig (...). После того, как я это сделал, я смог войти в наш конфигурационный файл журнала и сбросить все (как на обработчике файлов, так и в корне) на VERBOSE, и это сработало.

Конечно, сам оператор журнала не совсем изящен, потому что вы вызываете:

self.logger.log(VERBOSE,"Something very spammy")

а не

self.logger.verbose("Something very spammy")

Но я действительно не хотел изменять какой-либо код библиотеки журналов (был там, сделал это, есть футболка).

Спасибо всем!

И тем, кто думает, что ничто ниже DEBUG не требуется, больше силы для вас:)

4b9b3361

Ответ 1

DEBUG - это самый низкий уровень из тех, которые предоставляются модулем регистрации: ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'). Их числовые значения здесь: http://docs.python.org/howto/logging.html#logging-levels

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

>>> logging.addLevelName(5, "VERBOSE")

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

Ответ 2

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

logging.VERBOSE = 5
logging.addLevelName(logging.VERBOSE, "VERBOSE")
logging.Logger.verbose = lambda inst, msg, *args, **kwargs: inst.log(logging.VERBOSE, msg, *args, **kwargs)

Ответ 3

Ответ от @voitek отлично работает, но он забыл патч обезьяны logging.verbose.

logging.VERBOSE = 5
logging.addLevelName(logging.VERBOSE, "VERBOSE")
logging.Logger.verbose = lambda inst, msg, *args, **kwargs: inst.log(logging.VERBOSE, msg, *args, **kwargs)
logging.verbose = lambda msg, *args, **kwargs: logging.log(logging.VERBOSE, msg, *args, **kwargs)

Теперь это также будет работать;

logging.verbose(*args, **kwargs)

Ответ 4

Добавляя к ответу @sleepycal, вы также можете добавить подробный метод в LoggerAdapter:

logging.VERBOSE = 5
logging.addLevelName(logging.VERBOSE, "VERBOSE")
logging.Logger.verbose = lambda inst, msg, *args, **kwargs: inst.log(logging.VERBOSE, msg, *args, **kwargs)
logging.LoggerAdapter.verbose = lambda inst, msg, *args, **kwargs: inst.log(logging.VERBOSE, msg, *args, **kwargs)
logging.verbose = lambda msg, *args, **kwargs: logging.log(logging.VERBOSE, msg, *args, **kwargs)

Ответ 5

Попробовав множество решений, @sleepycal solution работал лучше всего. Другие решения в основном терпели неудачу, когда уровень отладки был изменен на лету, но этот сделал свое дело!