Как использовать разные форматы с одним и тем же обработчиком ведения журнала в python

Можно ли подключиться к одному пункту назначения (то есть к одному logging.getLogger("base.foo") ) с несколькими регистраторами (т.е. logging.getLogger("base.foo") и logging.getLogger("base.bar") ) и использовать разные форматы для каждого из регистраторы.

По моему мнению, можно назначить только один форматтер для каждого дескриптора. Может быть, можно связать форматтер с регистратором, а не с обработчиком?

2 Solutions collect form web for “Как использовать разные форматы с одним и тем же обработчиком ведения журнала в python”

Легко отправлять в разные record.name на основе record.name . Ниже приведен пример кода примера:

 import logging class DispatchingFormatter: def __init__(self, formatters, default_formatter): self._formatters = formatters self._default_formatter = default_formatter def format(self, record): formatter = self._formatters.get(record.name, self._default_formatter) return formatter.format(record) handler = logging.StreamHandler() handler.setFormatter(DispatchingFormatter({ 'base.foo': logging.Formatter('FOO: %(message)s'), 'base.bar': logging.Formatter('BAR: %(message)s'), }, logging.Formatter('%(message)s'), )) logging.getLogger().addHandler(handler) logging.getLogger('base.foo').error('Log from foo') logging.getLogger('base.bar').error('Log from bar') logging.getLogger('base.baz').error('Log from baz') 

Другой способ – открыть файл вручную и создать из него два обработчика потока с помощью разных форматировщиков.

Маленькое решение для отличного решения Дениса.

Система имен журналов на основе иерархической структуры:

name потенциально представляет собой иерархическое значение, разделенное периодом, например foo.bar.baz (хотя оно также может быть просто простым foo , например). Регистраторы, которые находятся ниже в иерархическом списке, являются дочерними элементами регистраторов выше в списке. Например, с учетом регистратора с именем foo регистраторы с именами foo.bar , foo.bar.baz и foo.bam являются потомками foo .

Например, когда вы устанавливаетеLevel () для некоторого регистратора, этот уровень будет также применяться к дочерним регистраторам. Вот почему вы, возможно, захотите, чтобы ваш форматировщик был использован для регистратора, а также для учетных записей. Например, форматировщик 'one.two' также должен применяться к 'one.two.three' (если нет форматирования для 'one.two.three' ). Вот версия DispatchingFormatter, которая выполняет работу (код Python 3):

 class DispatchingFormatter: """Dispatch formatter for logger and it's sub logger.""" def __init__(self, formatters, default_formatter): self._formatters = formatters self._default_formatter = default_formatter def format(self, record): # Search from record's logger up to it's parents: logger = logging.getLogger(record.name) while logger: # Check if suitable formatter for current logger exists: if logger.name in self._formatters: formatter = self._formatters[logger.name] break else: logger = logger.parent else: # If no formatter found, just use default: formatter = self._default_formatter return formatter.format(record) 

Пример:

 handler = logging.StreamHandler() handler.setFormatter(DispatchingFormatter({ 'one': logging.Formatter('%(message)s -> one'), 'one.two': logging.Formatter('%(message)s -> one.two'), }, logging.Formatter('%(message)s -> <default>'), )) logging.getLogger().addHandler(handler) print('Logger used -> formatter used:') logging.getLogger('one').error('one') logging.getLogger('one.two').error('one.two') logging.getLogger('one.two.three').error('one.two.three') # parent formatter 'one.two' will be used here logging.getLogger('other').error('other') # OUTPUT: # Logger used -> formatter used: # one -> one # one.two -> one.two # one.two.three -> one.two # other -> <default> 
 
Interesting Posts for Van-Lav
Python - лучший язык программирования в мире.