2009-05-18 12 views
24

Utilizzo la registrazione (importazione registrazione) per registrare i messaggi.registrazione con filtri

All'interno di un singolo modulo, sto registrando i messaggi a livello di debug (my_logger.debug ('msg'));

Alcuni di questi messaggi di debug provengono da function_a() e altri da function_b(); Mi piacerebbe essere in grado di abilitare/disabilitare la registrazione in base al fatto che provengano da a o da b;

Suppongo di dover utilizzare il meccanismo di filtraggio di Logging.

Qualcuno può, per favore, mostrarmi come il codice seguente dovrebbe essere strumentato per fare ciò che voglio? Grazie.

import logging 
logger= logging.getLogger("module_name") 

def function_a(...): 
    logger.debug("a message") 

def function_b(...): 
    logger.debug("another message") 

if __name__ == "__main__": 
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) 

    #don't want function_a()'s noise -> .... 
    #somehow filter-out function_a's logging 
    function_a() 

    #don't want function_b()'s noise -> .... 
    #somehow filter-out function_b's logging 
    function_b() 

Se ho scalato questo semplice esempio a più moduli e più funcs per modulo, sarei preoccupato per un sacco di logger;

Posso mantenere fino a 1 logger per modulo? Nota che i messaggi di log sono "strutturati", cioè se la funzione che sta registrando sta facendo un lavoro di analisi, tutti contengono un prefisso logger.debug ("parsing: xxx") - posso in qualche modo con una singola linea appena chiusa -non tutti i messaggi "parsing" (indipendentemente dal modulo/funzione che emettono il messaggio?)

risposta

36

Basta attuare una sottoclasse di logging.Filter: http://docs.python.org/library/logging.html#filter-objects. Avrà un metodo, filter(record), che esamina il registro e restituisce True per registrarlo o False per scartarlo. Quindi è possibile installare il filtro su Logger o Handler chiamando il metodo addFilter(filter).

Esempio:

class NoParsingFilter(logging.Filter): 
    def filter(self, record): 
     return not record.getMessage().startswith('parsing') 

logger.addFilter(NoParsingFilter()) 

O qualcosa del genere, in ogni caso.

+6

Ho dovuto aggiungere il filtro al gestore. –

15

Non utilizzare globale. È un incidente che aspetta di accadere.

Puoi dare ai tuoi logger "." - nomi separati che sono significativi per te.

È possibile controllarli come una gerarchia. Se si dispone di logger denominati a.b.c e a.b.d, è possibile controllare il livello di registrazione per a.b e modificare entrambi i logger.

È possibile avere un numero qualsiasi di registratori - sono economici.

Il modello di progettazione più comune è un logger per modulo. Vedi Naming Python loggers

Fare questo.

import logging 

logger= logging.getLogger("module_name") 
logger_a = logger.getLogger("module_name.function_a") 
logger_b = logger.getLogger("module_name.function_b") 

def function_a(...): 
    logger_a.debug("a message") 

def functio_b(...): 
    logger_b.debug("another message") 

if __name__ == "__main__": 
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) 
    logger_a.setLevel(logging.DEBUG) 
    logger_b.setLevel(logging.WARN) 

    ... etc ... 
+1

grazie S.Lott per la risposta; questo funzionerebbe; tuttavia, se ridimensionassi il mio semplice esempio in più moduli e più funcs per modulo, sarei preoccupato per molti logger; posso tenerlo giù a 1 logger per modulo? nota che i messaggi di log sono "strutturati", cioè se le funzioni che registrano stanno facendo un lavoro di analisi, tutti contengono un prefisso logger.debug ("parsing: ...") - posso in qualche modo con una singola riga basta chiudere tutti i messaggi di "parsing" (indipendentemente dal modulo/funzione che emette il messaggio?) –