2011-11-17 16 views
18

Sto registrando eventi nel mio codice Python usando il modulo di registrazione Python. Ho anche 2 file di log che desidero registrare, uno per contenere le informazioni dell'utente e l'altro un file di registro più dettagliato per gli sviluppatori. Ho impostato i due file di registrazione sui livelli desiderati (usr.log = INFO e dev.log = ERROR) ma non riesco a capire come limitare la registrazione al file usr.log in modo che solo i registri del livello INFO siano scritti al file di registro in contrasto con INFO e tutto il resto sopra ad es INFO, AVVERTENZA, ERRORE e CRITICO.Solo per livello di registrazione Python

Questo è fondamentalmente il mio codice: -

import logging 

logger1 = logging.getLogger('') 
logger1.addHandler(logging.FileHandler('/home/tmp/usr.log') 
logger1.setLevel(logging.INFO) 
logger2 = logging.getLogger('') 
logger2.addHandler(logging.FileHandler('/home/tmp/dev.log') 
logger2.setLevel(logging.ERROR) 

logging.critical('this to be logged in dev.log only') 
logging.info('this to be logged to usr.log and dev.log') 
logging.warning('this to be logged to dev.log only') 

Qualsiasi aiuto sarebbe grande grazie.

risposta

34

Sono in generale d'accordo con David, ma penso che sia necessario dire altro. Per parafrasare The Princess Bride - Non penso che questo codice significhi cosa pensi che significhi. Il codice ha:

logger1 = logging.getLogger('') 
... 
logger2 = logging.getLogger('') 

il che significa che logger1 e logger2 sono la stessa registratore, in modo che quando si imposta il livello di logger2 di errore che in realtà finiscono per impostare il livello di logger1 allo stesso tempo. Per ottenere due diversi logger, è necessario fornire due diversi nomi di logger. Per esempio:

logger1 = logging.getLogger('user') 
... 
logger2 = logging.getLogger('dev') 

Peggio ancora, si sta chiamando del modulo di registrazione critical(), info() e warning() metodi e in attesa che entrambi i logger otterranno i messaggi. Funziona solo perché hai usato la stringa vuota come nome per entrambi logger1 e logger2 e quindi non sono solo lo stesso registratore, ma sono anche il logger principale. Se si utilizzano nomi diversi per i due logger come suggerito, sarà necessario chiamare i metodi critical(), info() e warning() su ciascun registratore individualmente (ad esempio, saranno necessarie due chiamate anziché una sola).

Quello che penso che tu voglia veramente è avere due diversi handlers su un unico logger. Per esempio:

import logging 

mylogger = logging.getLogger('mylogger') 
handler1 = logging.FileHandler('usr.log') 
handler1.setLevel(logging.INFO) 
mylogger.addHandler(handler1) 
handler2 = logging.FileHandler('dev.log') 
handler2.setLevel(logging.ERROR) 
mylogger.addHandler(handler2) 
mylogger.setLevel(logging.INFO) 

mylogger.critical('A critical message') 
mylogger.info('An info message') 

Una volta effettuata questa modifica, quindi è possibile utilizzare filters come David ha già detto.Ecco un filtro campione rapida:

class MyFilter(object): 
    def __init__(self, level): 
     self.__level = level 

    def filter(self, logRecord): 
     return logRecord.levelno <= self.__level 

è possibile applicare il filtro a ciascuno dei due gestori di questo tipo:

handler1.addFilter(MyFilter(logging.INFO)) 
... 
handler2.addFilter(MyFilter(logging.ERROR)) 

Questa scelta limita ogni gestore solo a scrivere messaggi di log al livello specificato.

+0

@srgerg Grazie per aver trovato il tempo di spiegarlo, ora ha molto più senso. – user788462

+2

Per emettere il log solo al livello specificato, la condizione non dovrebbe essere 'logRecord.levelno == self .__ level' piuttosto che' <= '? – samstav

+0

Oh, suppongo che l'altro filtro incorporato farà il confronto '> ='. – samstav

7

Primo: questa è una cosa piuttosto strana da voler fare e mi colpisce come un lieve abuso del sistema di registrazione. Non riesco a immaginare nessuna situazione in cui abbia senso informare l'utente sul normale funzionamento del programma ma non sulle cose che sono più importanti. I livelli di registrazione dovrebbero essere usati per indicare l'importanza; se hai dei messaggi che interessano solo gli sviluppatori, dovresti utilizzare qualche altro meccanismo per distinguerli (come ad esempio il registratore a cui li hai inviati).

Detto questo, è possibile implementare il filtraggio arbitrario dei record di registro creando una sottoclasse Filter il cui metodo filter implementa i criteri desiderati e li installa sul gestore appropriato.

Problemi correlati