web-dev-qa-db-fra.com

Comment écrire un gestionnaire de journalisation personnalisé python?

Comment écrire une fonction de journal de console personnalisée pour afficher uniquement sur les messages de journal de la fenêtre de console sur une seule ligne (pas ajouter) jusqu'au premier enregistrement de journal normal.

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')

Pour que la sortie de la console ne soit que de trois lignes:

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

Avez-vous des suggestions sur la meilleure façon de mettre en œuvre cela?

50
koleto
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 __== '__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')

Notez qu'un seul gestionnaire est en cours d'enregistrement et l'argument de mot clé extra pour indiquer au gestionnaire qu'il doit rester sur une seule ligne. Il y a plus de logique dans la méthode emit() pour gérer les changements entre les messages qui doivent rester sur une seule ligne et les messages qui doivent avoir leur propre ligne.

53
Ethan Furman