2017-06-13 3 views
0

MemoryHandlerを終了するのを忘れると、flushOnClose=False(Python 3.6)でもログメッセージ 'debug'が表示されます。Python 3のログ - MemoryHandlerとflushOnCloseの動作

私は間違ったことをしていますか、これは予期された動作ですか?私はflushOnCloseが、ハンドルがどのように閉じられているか(すなわち、スクリプトが終了したとき)にかかわらず従うと考えていたでしょう。引数の

import logging.config 

logger = logging.getLogger(__name__) 
logger.setLevel(logging.DEBUG) 

# file handler, triggered by the memory handler 
fh = logging.FileHandler('log.txt') 
# set the logging level 
fh.setLevel(logging.DEBUG) 

# capacity is the number of records 
mh = logging.handlers.MemoryHandler(5, flushLevel=logging.ERROR, target=fh, flushOnClose=False) 

logger.addHandler(mh) 

logger.debug('debug') 

# mh.close() 

私は偽キュー

  • flushOnClose =に5つのメッセージを追加していない

    1. ので5, flushLevel=logging.ERROR, target=fh, flushOnClose=False「デバッグ」というメッセージは、そのためのスクリプトが終了したときに、表示すべきではありませんflushLevel
    からフラッシングを引き起こさないフラッシュ
  • デバッグすべきではありません

    mh.close()を使用すると、メッセージが期待通りにフラッシュされません。しかし、mh.close()(コメント付き)を除いてスクリプトが終了すると、設定すべきではないとの示唆にもかかわらず、単一のデバッグメッセージがフラッシュされるようです。

  • +1

    とにかく、ファイルを開いても最後に近いかどうかを判断することができます。 Pythonは情報を失わないためにファイルを閉じます:-)同様の動作...バッファに書き込んで無視すると、もちろん何も書き込まれません。 –

    答えて

    1

    私は、これは正しい動作だと思う:

    logger.debug(「デバッグ」) - >これは任意のフラッシュを待たずに、あなたのファイル「デバッグ」に出力します。

    申し訳ありません。はいデフォルトはTrueです。私は上記の追加を見て、私の意見では、動作が正常であるという意味で、終了しないとすべてが実行終了時にフラッシュされる(これは間違ったものをデバッグするために典型的なことです)。終了する場合、メッセージはバッファに追加され、 "False"はメッセージをバッファ内で破棄させます。それは正しい行動ではありませんか?

    またflushOnCloseは、以下のようにハンドラクラスに存在しません:

    class MemoryHandler(BufferingHandler): 
        """ 
        A handler class which buffers logging records in memory, periodically 
        flushing them to a target handler. Flushing occurs whenever the buffer 
        is full, or when an event of a certain severity or greater is seen. 
        """ 
        def __init__(self, capacity, flushLevel=logging.ERROR, target=None): 
         """ 
         Initialize the handler with the buffer size, the level at which 
         flushing should occur and an optional target. 
    
         Note that without a target being set either here or via setTarget(), 
         a MemoryHandler is no use to anyone! 
         """ 
         BufferingHandler.__init__(self, capacity) 
         self.flushLevel = flushLevel 
         self.target = target 
    
        def shouldFlush(self, record): 
         """ 
         Check for buffer full or a record at the flushLevel or higher. 
         """ 
         return (len(self.buffer) >= self.capacity) or \ 
           (record.levelno >= self.flushLevel) 
    
        def setTarget(self, target): 
         """ 
         Set the target handler for this handler. 
         """ 
         self.target = target 
    
        def flush(self): 
         """ 
         For a MemoryHandler, flushing means just sending the buffered 
         records to the target, if there is one. Override if you want 
         different behaviour. 
    
         The record buffer is also cleared by this operation. 
         """ 
         self.acquire() 
         try: 
          if self.target: 
           for record in self.buffer: 
            self.target.handle(record) 
           self.buffer = [] 
         finally: 
          self.release() 
    
        def close(self): 
         """ 
         Flush, set the target to None and lose the buffer. 
         """ 
         try: 
          self.flush() 
         finally: 
          self.acquire() 
          try: 
           self.target = None 
           BufferingHandler.close(self) 
          finally: 
           self.release() 
    

    とにかく行動はあなたがファイルを開いた場合でも、あなたは、今日が近い場合かを決めることができるという意味で、正常です終わり。最終的には、情報を失わないようにファイルが閉じられます:-)

    +0

    申し訳ありませんが、私はこのPython 3を使用していることを忘れています。 Python 3.6では、flushOnCloseパラメータが追加されました https://docs.python.org/3/library/logging.handlers.html#memoryhandler – hobboy

    +0

    さらに、私の理解は、MemoryHandler(私が設定した方法)はフラッシュしないでください5つのログエントリがあるまで – hobboy

    +0

    はい私はそれを見つけました。クラスlogging.handlers.MemoryHandler(capacity、flushLevel = ERROR、target = None、flushOnClose = True)このインスタンスは、容量のバッファサイズで初期化されます。 flushLevelが指定されていない場合、ERRORが使用されます。ターゲットが指定されていない場合、このハンドラが有用な処理を行う前にターゲットをsetTarget()を使用して設定する必要があります。 flushOnCloseがFalseに指定されている場合、ハンドラが閉じられるとバッファはフラッシュされません。指定されていない場合、またはTrueとして指定されている場合、バッファをフラッシュする前の動作は、ハンドラが閉じられたときに発生します。 –

    関連する問題