import logging logging.LoggerAdapter(logger, extra)
logger
- базовый экземпляр Logger
,extra
- dict-подобным объект.LoggerAdapter
.Функция LoggerAdapter()
модуля logging
возвращает объект LoggerAdapter
, инициализированный базовым экземпляром Logger
и dict-подобным объектом extra
.
LoggerAdapter
.process(msg, kwargs)
:Метод process()
изменяет аргументы сообщения и/или ключевые аргументы, передаваемые в журнал для того, чтобы вставить контекстную информацию. Эта реализация принимает объект, переданный как дополнительный в конструктор и добавляет его в kwargs
, используя ключ 'extra'
. Возвращаемое значение представляет собой кортеж (msg kwargs)
, который возможно имеет измененные версии переданных аргументов.
В дополнение к вышесказанному методу LoggerAdapter
поддерживает следующие методы объекта Logger
: debug()
, info()
, warning()
, error()
, exception()
, log()
, isEnabledFor()
, getEffectiveLevel()
, SetLevel()
и hasHandlers()
. Эти методы имеют те же подписи, что и их аналоги в Logger
, поэтому можно использовать два типа экземпляров взаимозаменяемо.
Когда вызывается один из методов ведения журнала экземпляра LoggerAdapter
, то он делегирует вызов базовому экземпляру Logger
, передавая его конструктору и организует передачу контекстной информации в делегированном вызове.
Вот фрагмент из кода LoggerAdapter
:
def debug(self, msg, /, *args, **kwargs): """ Delegate a debug call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.debug(msg, *args, **kwargs)
Метод process()
в LoggerAdapter
- это место, где контекстная информация добавляется в вывод журнала. Метод принял msg
и kwargs
вызова, обработал их и передает уже измененные версии этих аргументов для использования в вызове базовому регистратору logger
. Реализация этого метода по умолчанию оставляет сообщение в покое, но вставляет дополнительный ключ ‘extra’
в kwargs
, значение которого является dict-подобным объектом. Если передать дополнительный аргумент extra
в вызове адаптеру, то он будет перезаписан.
Преимущество использования 'extra'
заключается в том, что значения в объекте dict-like объединяются в экземпляр LogRecord
, что позволяет использовать настроенные строки с экземплярами Formatter
, которые знают о ключах dict-подобного объекта.
Если нужно добавить контекстную информацию в строку сообщения, то просто нужно создать подкласс LoggerAdapter
и переопределить метод process()
, который сделает то что нужно. Вот простой пример:
class CustomAdapter(logging.LoggerAdapter): """ В примере адаптер ожидает, что переданный в dict-подобный объект будет иметь ключ 'connid', значение которого в скобках добавляется к сообщению журнала. """ def process(self, msg, kwargs): return '[%s] %s' % (self.extra['connid'], msg), kwargs
Который можно использовать так:
logger = logging.getLogger(__name__) adapter = CustomAdapter(logger, {'connid': some_conn_id})
Тогда любые события, которые записываются в адаптер, будут иметь добавленное к сообщениям журнала значение some_conn_id
.