只在记录器上检查第一个过滤器

时间:2016-07-08 10:54:39

标签: python multithreading python-2.7 logging filter

所以,现在,我有一个生成多个线程的进程,每个线程都有自己的实例数据。我需要将特定于上下文的信息注入到在派生线程类内部的各种方法中调用的每个日志记录语句中(在这种情况下,特定于上下文的信息是触发线程生成的人的电子邮件) 。

以下是我目前使用的过滤器

class InjectionFilter(logging.Filter):                                                             
  def __init__(self, runner):                                                                    
    self.runner = runner                                                                       

  def filter(self, record):                                                                      
    record.email = self.runner.authorEmail                                         
    return (record.threadName == self.runner.getName())  

"转轮"在这种情况下是一个类是Thread的子类,因此能够调用getName()。

现在,对于过滤器,每次创建新线程时,都会通过将新过滤器实例添加到运行器类的__init__方法中的日志记录实例来实例化新过滤器。

class ThreadRunner(Thread):
  def __init__(self, other_info):
    ... other things set here ...
    ifilter = InjectionFilter(self)
    _log.addFilter(ifilter)

其中_log是我所有这些线程的全局日志记录实例。 过滤器添加完美! 我可以致电_log.filters并查看每个过滤器。 这工作得很好。

什么不工作,在读取日志记录语句时,实际上只检查了第一个过滤器。

我在过滤器中添加了调试语句,以检查并查看其中的内容。 eprint只是打印到sys.stderr

的辅助方法
def filter(self, record):                                                                      
  record.email = self.runner.authorEmail                                          
  eprint("Record threadname is %s" % record.threadName)                                      
  eprint("Runner threadname is %s" % self.runner.getName())                                  
  eprint("Runner equals Record: %s" % (record.threadName == self.runner.getName()))
  return (record.threadName == self.runner.getName())

当我启动管理器并生成多个线程时,我每次都会得到相同的过滤器检查,始终是创建的第一个过滤器。

示例日志输出

Record threadname is Thread-52
Runner threadname is Thread-52
Runner equals Record: True
...
Record threadname is Thread-53
Runner threadname is Thread-52
Runner equals Record: False
...
Record threadname is Thread-54
Runner threadname is Thread-52
Runner equals Record: False

它只将它与Thread-52进行比较,后者是第一个创建的过滤器。但是,如果我打印出应用于记录器的所有过滤器

for fil in _log.filters:
  print(fil.runner.getName())

我得到了

Thread-52
Thread-53
Thread-54

所以我知道所有的过滤器都应用于记录器,但由于某些原因它们都没有被比较。在第一个线程之后的每个日志语句中,我得到False的filter filter语句。

Python只检查第一个过滤器吗?我设置错了吗?我在这里错过了什么吗?

我觉得这应该非常简单,但Python的日志文档对我来说并不是最有意义的。

如果您需要更多背景信息,或者我不清楚,请告知我们。我想完成这件事。哈哈

1 个答案:

答案 0 :(得分:0)

想出来,万一有人在将来遇到类似这样的事情(或者你不会因为你是一个比我更好的程序员,哈哈)

对于使用Python进行日志记录,只有一个过滤器必须失败才能删除整个日志消息。我认为它会检查过滤器,看看它们中是否至少有一个过去了,但我意识到这个思维过程现在是如何被打破的。

因此,为了解决这个问题,我为每个生成的线程实例化了一个新的处理程序,并将一个新的过滤器实例应用于该处理程序,然后我将处理程序应用于_log实例。

现在,_log有许多处理程序,每个处理程序都有一个过滤器。日志记录语句将检查每个处理程序,只有具有适当过滤器的那个将被发送通过。 :)

有效!