【发布时间】: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