2010-06-25 12 views
39

Come scrivere la funzione di registro della console personalizzata per l'output solo sui messaggi di log della finestra della console su una singola riga (non accodata) fino al primo record del registro normale.Come scrivere un gestore di registrazione python personalizzato?

progress = ProgressConsoleHandler() 
console = logging.StreamHandler() 

logger = logging.getLogger('test') 
logger.setLevel(logging.DEBUG) 
logger.addHandler(console) 
logger.addHandler(progress) 

logger.info('test1') 
for i in range(3): 
    logger.progress('remaining %d seconds' % i) 
    time.sleep(1) 
logger.info('test2') 

modo che l'uscita della console è solo tre linee:

INFO: test1 
remaining 0 seconds... 
INFO: test2 

Eventuali suggerimenti sul modo migliore su come implementare questo?

+0

Dove è definito 'log'? ... a parte il 'log' in' math' ... –

+0

La maggior parte di questi dovrebbe aiutare: http://stackoverflow.com/search?q=python+logging+handler –

+0

possibile duplicato di [Reindirizzare l'output di registrazione usando l'abitudine gestore di registrazione] (http://stackoverflow.com/questions/2819791/redirect-logging-output-using-custom-logging-handler) –

risposta

45
import logging 
class ProgressConsoleHandler(logging.StreamHandler): 
    """ 
    A handler class which allows the cursor to stay on 
    one line for selected messages 
    """ 
    on_same_line = False 
    def emit(self, record): 
     try: 
      msg = self.format(record) 
      stream = self.stream 
      same_line = hasattr(record, 'same_line') 
      if self.on_same_line and not same_line: 
       stream.write(self.terminator) 
      stream.write(msg) 
      if same_line: 
       stream.write('... ') 
       self.on_same_line = True 
      else: 
       stream.write(self.terminator) 
       self.on_same_line = False 
      self.flush() 
     except (KeyboardInterrupt, SystemExit): 
      raise 
     except: 
      self.handleError(record) 
if __name__ == '__main__': 
    import time 
    progress = ProgressConsoleHandler() 
    console = logging.StreamHandler() 

    logger = logging.getLogger('test') 
    logger.setLevel(logging.DEBUG) 
    logger.addHandler(progress) 

    logger.info('test1') 
    for i in range(3): 
     logger.info('remaining %d seconds', i, extra={'same_line':True}) 
     time.sleep(1) 
    logger.info('test2') 

Si noti che solo un gestore viene registrato, e la parola chiave extra argomento per lasciare che il gestore sa che dovrebbe rimanere su una sola riga. C'è più logica nel metodo emit() per gestire le modifiche tra i messaggi che dovrebbero rimanere su una riga e i messaggi che devono avere la propria linea.

+9

FYI per chi si imbatte in questo: l'attributo 'terminator' è disponibile solo in Python> = 3.2, vedere https://mail.python.org/pipermail/python-list/2010-October/590223.html – Pat

Problemi correlati