Piccola soluzione all'eccellente soluzione di Denis.
Logging name system base alla struttura gerarchica:
Il name
è potenzialmente un valore gerarchico periodo separati, come foo.bar.baz
(ma potrebbe anche essere semplicemente foo
, per esempio). I logger più in basso nell'elenco gerarchico sono figli dei logger più in alto nell'elenco. Ad esempio, dato un logger con un nome di foo
, i logger con i nomi di foo.bar
, foo.bar.baz
e foo.bam
sono tutti discendenti di foo
.
Ad esempio, quando si utilizza il logger setLevel(), questo livello verrà applicato anche ai registratori di dati secondari. Ecco perché potresti volere che il tuo formattatore venga usato per il logger e anche per i logger dei bambini. Ad esempio, il programma di formattazione 'one.two'
deve essere applicato anche al logger 'one.two.three'
(se non è impostato alcun formattatore per 'one.two.three'
). Ecco la versione di DispatchingFormatter che fanno lavoro (codice 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)
Esempio:
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>
fonte
2016-01-06 06:07:24
Eccellente, soluzione elegante. Per la cronaca funziona anche su record.levelno, in modo che la chiave del dizionario di formattazione possa essere 'logging.DEBUG' invece di' 'base.foo'' – lorenzog