Я бы хотел, чтобы в моем приложении был уровень логирования TRACE (5), поскольку я не думаю, что этого debug()
достаточно. Кроме log(5, msg)
того, я не хочу. Как я могу добавить настраиваемый уровень ведения журнала в средство ведения журнала Python?
У меня есть mylogger.py
следующий контент:
import logging
@property
def log(obj):
myLogger = logging.getLogger(obj.__class__.__name__)
return myLogger
В своем коде я использую его следующим образом:
class ExampleClass(object):
from mylogger import log
def __init__(self):
'''The constructor with the logger'''
self.log.debug("Init runs")
Сейчас я хочу позвонить self.log.trace("foo bar")
Заранее спасибо за вашу помощь.
Изменить (8 декабря 2016 г.): я изменил принятый ответ на pfa, который, IMHO, является отличным решением, основанным на очень хорошем предложении Эрика С.
источник
logging.DEBUG_LEVEL_NUM = 9
чтобы вы могли получить доступ к этому уровню отладки везде, где вы импортируете регистратор в свой код?DEBUG_LEVEL_NUM = 9
вам следует определитьсяlogging.DEBUG_LEVEL_NUM = 9
. Таким образом, вы сможете использовать такlog_instance.setLevel(logging.DEBUG_LEVEL_NUM)
же, как вы используете правильное знаниеlogging.DEBUG
илиlogging.INFO
logging.DEBUGV = DEBUG_LEVELV_NUM
иlogging.__all__ += ['DEBUGV']
Второе не очень важно, но первое необходимо, если у вас есть код, который динамически регулирует уровень ведения журнала, и вы хотите иметь возможность делать что-то вродеif verbose: logger.setLevel(logging.DEBUGV)
`Я взял ответ «не видеть лямбда» и должен был изменить место добавления log_at_my_log_level. Я тоже видел проблему, которую создал Пол: «Я не думаю, что это работает. Вам не нужен логгер в качестве первого аргумента в log_at_my_log_level?» Это сработало для меня
источник
__init__.py
и будьте счастливы: DTypeError: not all arguments converted during string formatting
но он отлично работает с *. (Python 3.4.3). Это проблема с версией Python или что-то, что мне не хватает?AttributeError: module 'logging' has no attribute 'debugv'
Объединив все существующие ответы с кучей опыта использования, я думаю, что составил список всех вещей, которые необходимо сделать, чтобы обеспечить полное беспрепятственное использование нового уровня. Следующие шаги предполагают, что вы добавляете новый уровень
TRACE
со значениемlogging.DEBUG - 5 == 5
:logging.addLevelName(logging.DEBUG - 5, 'TRACE')
необходимо вызвать для внутренней регистрации нового уровня, чтобы на него можно было ссылаться по имени.logging
себе для последовательности:logging.TRACE = logging.DEBUG - 5
.trace
необходимо добавить вlogging
модуль. Он должен вести себя так же , какdebug
,info
и т.д.trace
необходимо добавить к текущему настроенному классу регистратора. Поскольку это не на 100% гарантированоlogging.Logger
, используйтеlogging.getLoggerClass()
вместо этого.Все шаги показаны в методе ниже:
источник
Oldest
, и вы убедитесь, что это лучший ответ из всех!args
вlogForLevel
осуществлении намеренного / требуется?Этот вопрос довольно старый, но я только что затронул ту же тему и нашел способ, похожий на уже упомянутые, который мне кажется немного чище. Это было протестировано на 3.4, поэтому я не уверен, существуют ли используемые методы в более старых версиях:
источник
get
и чтоsetLoggerClass
именно делают и зачем они нужны?TRACE
уровень в библиотеку ведения журнала по умолчанию. +1Кто начал плохую практику использования внутренних методов (
self._log
) и почему каждый ответ основан на этом ?!self.log
Вместо этого можно было бы использовать питоническое решение, чтобы вам не пришлось возиться с какими-либо внутренними вещами:источник
Мне проще создать новый атрибут для объекта регистратора, который передает функцию log (). Я думаю, что модуль logger предоставляет addLevelName () и log () именно по этой причине. Таким образом, не нужны подклассы или новый метод.
сейчас
должен работать как положено.
источник
_log
, а неlog
.Хотя у нас уже есть много правильных ответов, на мой взгляд, более питоническим является следующее:
Если вы хотите использовать
mypy
в своем коде, рекомендуется добавить,# type: ignore
чтобы подавить предупреждения от добавления атрибута.источник
logging.trace = partial(logging.log, logging.TRACE) # type: ignore
?Я думаю, вам придется
Logger
создать подкласс класса и добавить вызываемый метод,trace
который в основном вызываетLogger.log
с уровнем нижеDEBUG
. Я не пробовал это, но это то, что указано в документации .источник
logging.getLogger
чтобы вернуть свой подкласс вместо встроенного класса.setLoggerClass(MyClass)
а затем звонитьgetLogger()
как обычно ...Советы по созданию собственного регистратора:
_log
, использоватьlog
(проверять не обязательноisEnabledFor
)getLogger
, поэтому вам нужно будет установить класс черезsetLoggerClass
__init__
класс для регистратора, если вы ничего не хранитеПри вызове этого регистратора используйте,
setLoggerClass(MyLogger)
чтобы сделать его регистратором по умолчанию изgetLogger
Вам нужно
setFormatter
,setHandler
иsetLevel(TRACE)
наhandler
и наlog
сам фактически з этой низкого уровня трассировкиисточник
Это сработало для меня:
Проблема lambda / funcName исправлена с помощью logger._log, как указал @marqueed. Я думаю, что использование лямбда выглядит немного чище, но недостатком является то, что он не может принимать аргументы ключевых слов. Сам я этим никогда не пользовался, так что ничего страшного.
источник
По моему опыту, это полное решение проблемы оператора ... чтобы не видеть "лямбда" как функцию, в которой отправляется сообщение, идите глубже:
Я никогда не пробовал работать с автономным классом регистратора, но думаю, что основная идея та же (используйте _log).
источник
logger
первый аргументlog_at_my_log_level
?Дополнение к примеру Mad Physicists, чтобы правильно указать имя файла и номер строки:
источник
на основе закрепленного ответа я написал небольшой метод, который автоматически создает новые уровни ведения журнала
config может что-то вроде этого:
источник
В качестве альтернативы добавлению дополнительного метода в класс Logger я бы рекомендовал использовать этот
Logger.log(level, msg)
метод.источник
Я запутался; с python 3.5, по крайней мере, он просто работает:
вывод:
источник
logger.trace('hi')
что я считаю главной цельюЕсли кому-то нужен автоматический способ динамического добавления нового уровня ведения журнала в модуль ведения журнала (или его копию), я создал эту функцию, расширив ответ @pfa:
источник
setattr