2017-06-13 42 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() 

对于参数5, flushLevel=logging.ERROR, target=fh, flushOnClose=False“调试”消息不应该被显示,因为

  1. 我还没有加入5个消息到队列
  2. flushOnClose =假,因此当脚本结束有不应该是齐平的
  3. 调试不会触发从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,则在处理程序关闭时会发生先前刷新缓冲区的行为。 –