web-dev-qa-db-ja.com

カスタムpythonロギングハンドラを書く方法は?

最初の通常のログレコードまで、コンソールウィンドウのログメッセージのみを1行で(追加ではなく)出力するカスタムコンソールログ関数を記述する方法。

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

そのため、コンソール出力は3行のみです。

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

これを実装する方法に関する最善の方法に関する提案はありますか?

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

登録されているハンドラは1つだけであり、extraキーワード引数を使用すると、ハンドラに1行のままにしておく必要があることが通知されます。 emit()メソッドには、1行のままにする必要があるメッセージと、独自の行が必要なメッセージとの間の変更を処理するためのロジックがあります。

53
Ethan Furman