2010-02-15 15 views
95

Sto usando il modulo python logging e voglio disabilitare la registrazione della console per un po 'di tempo ma non funziona.Come disabilitare e riattivare la registrazione della console in Python?


    #!/usr/bin/python 
    import logging 

    logger = logging.getLogger() # this gets the root logger 
    # ... here I add my own handlers 
    #logger.removeHandler(sys.stdout) 
    #logger.removeHandler(sys.stderr) 

    print logging.handlers 
    # this will print [<logging.StreamHandler instance at ...>] 
    # but I may have other handlers there that I want to keep 

    logger.debug("bla bla") 

Il codice di cui sopra mostra il "bla bla", a stdout e non so come posso tranquillamente disabilitare il gestore console. Come posso essere sicuro di rimuovere temporaneamente lo streamhandler della console e non un altro?

risposta

140

ho trovato una soluzione per questo:

logger = logging.getLogger('my-logger') 
logger.propagate = False 
# now if you use logger it will not log to console. 

Questo consentirà di evitare la registrazione di essere inviare al logger superiore che include la registrazione della console.

+0

Questo funziona per Python 3.5. Grazie! –

+1

Non penso che questa sia una buona soluzione. Non propagarsi ai registratori più alti potrebbe avere altre conseguenze indesiderabili. – lfk

+1

Se si desidera filtrare solo il messaggio al di sotto di un determinato livello di registro (ad esempio, tutti i messaggi 'INFO'), è possibile modificare la seconda riga in qualcosa come' logger.setLevel (logging.WARNING) ' –

2

Non conosco il modulo di registrazione molto bene, ma lo sto utilizzando nel modo in cui di solito desidero disabilitare solo i messaggi di debug (o informazioni). È possibile utilizzare Handler.setLevel() per impostare il livello di registrazione su CRITICO o superiore.

Inoltre, è possibile sostituire sys.stderr e sys.stdout con un file aperto per la scrittura. Vedi http://docs.python.org/library/sys.html#sys.stdout. Ma non lo consiglierei.

+0

Questo potrebbe funzionare se logger.handlers fosse contenente qualcosa, attualmente è '[]'. – sorin

8

Non è necessario deviare lo stdout. Qui è migliore modo per farlo:

import logging 
class MyLogHandler(logging.Handler): 
    def emit(self, record): 
     pass 

logging.getLogger().addHandler(MyLogHandler()) 

Un modo ancora più semplice è:

logging.getLogger().setLevel(100) 
+1

In Python 2.7+ questo è disponibile come [NullHandler()] (https://docs.python.org/2/library/logging.handlers.html # nullhandler) – Pierre

52

è possibile utilizzare:

logging.basicConfig(level=your_level) 

dove your_level è uno di quelli:

 'debug': logging.DEBUG, 
     'info': logging.INFO, 
     'warning': logging.WARNING, 
     'error': logging.ERROR, 
     'critical': logging.CRITICAL 

Quindi, se si imposta your_level a logging.CRITICAL, si otterrà solo messaggi critici inviati da:

logging.critical('This is a critical error message') 

Impostazione your_level a logging.DEBUG mostrerà tutti i livelli di registrazione.

Per ulteriori informazioni, si prega di dare un'occhiata a logging examples.

Allo stesso modo per modificare il livello per ogni Handler utilizzare Handler.setLevel() funzione.

import logging 
import logging.handlers 

LOG_FILENAME = '/tmp/logging_rotatingfile_example.out' 

# Set up a specific logger with our desired output level 
my_logger = logging.getLogger('MyLogger') 
my_logger.setLevel(logging.DEBUG) 

# Add the log message handler to the logger 
handler = logging.handlers.RotatingFileHandler(
      LOG_FILENAME, maxBytes=20, backupCount=5) 

handler.setLevel(logging.CRITICAL) 

my_logger.addHandler(handler) 
+1

Questa è generalmente un'informazione utile, ma la domanda ha chiesto come disabilitare la registrazione della console, non come aggiungere un gestore aggiuntivo. se dovessi esaminare my_logger.handlers con il codice sopra riportato sull'esempio originale, vedresti due gestori: il nuovo gestore file e il gestore flusso originale. – Joe

59

io uso:

logger = logging.getLogger() 
logger.disabled = True 
... whatever you want ... 
logger.disabled = False 
+2

questo funziona anche con il' logging 'livello modulo per disabilitare la registrazione * interamente *, ad esempio:' registrazione di importazione; logging.disable (logging.CRITICAL); ': https://docs.python.org/2/library/logging.html#logging.disable – lsh

35

(domanda morto da tempo, ma per i ricercatori futuri)

Più vicino a codice/intento del manifesto originale, questo funziona per me sotto python 2.6

#!/usr/bin/python 
import logging 

logger = logging.getLogger() # this gets the root logger 

lhStdout = logger.handlers[0] # stdout is the only handler initially 

# ... here I add my own handlers 
f = open("/tmp/debug","w")   # example handler 
lh = logging.StreamHandler(f) 
logger.addHandler(lh) 

logger.removeHandler(lhStdout) 

logger.debug("bla bla") 

Il Gotcha ho dovuto lavorare fuori è stato quello di rimuovere il gestore stdout dopo l'aggiunta di una nuova; il codice logger sembra riaggiungere automaticamente lo stdout se non sono presenti gestori.

+2

Concordato. Questa è la risposta corretta. – obsoleter

25

Ci sono alcune risposte davvero belle qui, ma a quanto pare il più semplice non è preso troppo in considerazione (solo da infinito).

root_logger = logging.getLogger() 
root_logger.disabled = True 

Disabilita il logger root e quindi tutti gli altri logger. Non ho ancora provato, ma dovrebbe essere anche il più veloce.

Dal codice di registrazione in python 2.7 Vedo questo

def handle(self, record): 
    """ 
    Call the handlers for the specified record. 

    This method is used for unpickled records received from a socket, as 
    well as those created locally. Logger-level filtering is applied. 
    """ 
    if (not self.disabled) and self.filter(record): 
     self.callHandlers(record) 

Il che significa che quando è disattivata alcun gestore si chiama, e dovrebbe essere più efficiente che il filtraggio ad un valore molto elevato o l'impostazione di una no- op handler per esempio.

+0

Ottenere il logger principale ha risolto il mio problema. Grazie – cgl

+1

Questa è la migliore risposta alla domanda. – user1823280

+1

A meno che non stia facendo qualcosa di sbagliato, questo disabilita solo il logger root e non tutti creati come 'log = logging.getLogger (__ name __)' – starfry

28

Contesto direttore

import logging 
class DisableLogger(): 
    def __enter__(self): 
     logging.disable(logging.CRITICAL) 
    def __exit__(self, a, b, c): 
     logging.disable(logging.NOTSET) 

Esempio di utilizzo:

with DisableLogger(): 
    do_something() 
+0

Mi piace molto questo idioma, ma preferirei disabilitare un particolare spazio dei nomi. Ad esempio, voglio solo il root logger temporaneamente disabilitato. Sebbene utilizzi questo idioma, dovremmo essere in grado di aggiungere/rimuovere temporaneamente gestori e simili. – Chris

2

Si potrebbe anche:

handlers = app.logger.handlers 
# detach console handler 
app.logger.handlers = [] 
# attach 
app.logger.handlers = handlers 
6

Per disattivare completamente la registrazione:

logging.disable(sys.maxint) 

Per attivare la registrazione:

logging.disable(logging.NOTSET) 

Altre risposte fornire arounds di lavoro che non risolvono completamente il problema, come ad esempio

logging.getLogger().disabled = True 

e, per un po 'più grande di n 50,

logging.disable(n) 

Il problema con la prima soluzione è che funziona solo per il root logger. Altri logger creati usando, per esempio, logging.getLogger(__name__) non sono disabilitati con questo metodo.

La seconda soluzione ha effetto su tutti i registri. Ma limita uscita a livelli superiori a quella data, così si potrebbe ignorare che accedendo con un livello superiore a 50.

che possono essere prevenute da

logging.disable(sys.maxint) 

che, per quanto posso dire (dopo aver esaminato il source) è l'unico modo per disabilitare completamente la registrazione.

Problemi correlati