Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write custom python logging handler?

How to write custom console log function to output only on the console window log messages on a single line (not append) until the first regular log record.

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

So that the console output is only three lines:

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

Any suggestions on the best way on how to implement this?

like image 631
koleto Avatar asked Jun 25 '10 12:06

koleto


People also ask

What is Handler in logging Python?

Python Logging Handler The log handler is the component that effectively writes/displays a log: Display it in the console (via StreamHandler), in a file (via FileHandler), or even by sending you an email via SMTPHandler, etc. Each log handler has 2 important fields: A formatter which adds context information to a log.

How do I create a multiple logging level in Python?

You can set a different logging level for each logging handler but it seems you will have to set the logger's level to the "lowest". In the example below I set the logger to DEBUG, the stream handler to INFO and the TimedRotatingFileHandler to DEBUG. So the file has DEBUG entries and the stream outputs only INFO.


1 Answers

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

Notice that only one handler is being registered, and the extra keyword argument to let the handler know it should stay on one line. There is more logic in the emit() method to handle changes between messages that should stay on one line and messages that need to have their own line.

like image 151
Ethan Furman Avatar answered Oct 01 '22 03:10

Ethan Furman