【问题标题】:Only first filter being checked on logger仅在记录器上检查第一个过滤器
【发布时间】:2016-11-10 22:05:00
【问题描述】:

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

这是我目前使用的过滤器

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

在这种情况下,“Runner”是一个类,它是 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 用于在第一个线程之后的每个日志语句上的过滤器比较语句。

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

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

如果您需要更多上下文,或者我不清楚,请告诉我。我想完成这件事。哈哈

【问题讨论】:

    标签: python multithreading python-2.7 logging filter


    【解决方案1】:

    想通了,以防将来有人遇到这样的事情(或者你可能不会因为你是一个比我更好的程序员,哈哈)

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

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

    现在,_log 有许多处理程序,每个处理程序都有一个过滤器。日志语句将检查每个处理程序,并且只有具有适当过滤器的处理程序才会通过。 :)

    有效!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-23
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多