使用python记录器模块实现计数

时间:2014-12-30 23:18:43

标签: python logging

我试图创建一个能够很好地处理结合的python记录器处理程序。例如,我可能会每秒记录一次。比如说,10秒之后,我想在logging.info中发现这个事情在那10秒内发生了10,000次。我有一些设置来做它,但它似乎有点icky,我想知道是否有任何python日志专家可以提供帮助。理想情况下,我想让我的计数器处理程序定期将计数记录传递给标准处理程序...

这是我到目前为止所拥有的:

class CounterHandler(logging.Handler):
  '''
  This handler is to log only counts of messages.  
  So, for instance, suppose we want to logging.debug event A 
  which happens about once a millisecond, but we may want to 
  logging.info every second how many times event A happened 
  during that second.
  '''
  def __init__(self, pattern, message, logger, howoften = 1, timer = time.time, leastlevel = logging.NOTSET, messagelevel = logging.INFO, plot = False):
    '''
    pattern: the regex pattern in log messages to count
    leastlevel: the least logging level to count
    handler: the handler to hand accumulated counts to
    message: the message to log when we log accumulated counts
    messagelevel: the logging level at which to log accumulated counts
    howoften: how often to log accumulated counts
    timer: the timer to use (default is real time, but you can use, e.g. simpy time or something else)
    '''
    logging.Handler.__init__(self)
    self._regex = re.compile(pattern)
    self._msg = message
    self._messagelevel = messagelevel
    self._leastlevel = level
    self._logger = logger
    self._count = 0
    self._howoften = howoften
    self._timer = timer

    self.stopper = threading.Event()
    self._propogation_thread = threading.Thread(target=self._propogate, args=(self.stopper, timer))
    self._propogation_thread.daemon = True
    self._propogation_thread.start()

  def _dump(self):
    self._logger.log(self._messagelevel, 
                     "{} happened {} times by time {}".format(self._msg, 
                                                              self._count, 
                                                              self._timer()))


  def _propogate(self, stopper, timer):
    '''
    This is a thread that dumps the counts every so often 
    '''
    lasttime = timer()
    while not stopper.is_set():
      if lasttime + self._howoften < timer():
        self._dump()

  def emit(self, record):
    if record.level >= self._level and regex.match(record.message):
      self._count += 1

编辑: @Reut,这个问题的另一面实际上很复杂。我想把它交给另一个处理程序的原因是因为我想要灵活处理我得到的计数。我有一个图形实时计算的模块,但我也有一个日志文件,输出到它会很好。在这种情况下,似乎我应该按照链接处理程序的方式做一些事情,然后我可以根据需要添加或减少功能。 Viz:

The big picture:
                                               ,-> LogFileHandler    
My Code -> Log Message -> Logger -> LogRecord <                    ,-> GrapherHandler
                                               `-> CounterHandler <
                                                                   `-> LogFileHandler

1 个答案:

答案 0 :(得分:0)

在我看来,写入处理程序更容易,log.infolog.debug发生后发送1000次。在日志中,您有日期时间,因此您可以计算每秒,分钟,小时等的log.debug的平均数量。

要编写此处理程序,您可以基于https://docs.python.org/2/library/logging.handlers.html#timedrotatingfilehandler