繁体   English   中英

如何将来自不同线程的消息记录到不同的文件?

[英]How to log messages from different threads to different files?

我有一个Driver.py脚本,它根据给定的输入调用多个threads 线程基本上是运行一个选定的 object 的模块。 所以Driver.py可能会调用thread_1.run()thread_2.run()thread_3.run() ,并继续其进程。

Driver.py将其 output 记录到 main.log 文件夹中,我希望线程将其 output 记录到每个文件名中。 Driver.pyThreads还使用在不同文件上定义的通用模块,它们还记录信息。

我首先在Driver上调用setup_load("main.log") ,然后在每个Thread中调用setup_load(f"thread_{jobid}.log") 我意识到当调用Thread时,现在 Driver.py 写入线程的日志文件。 我可能会在 Thread 中使用不同的记录器,但是当 Thread 调用另一个模块时,因为这些通用模块正在使用import logging ,它们会写入根记录器定义的文件名。


=>是否可以将来自不同线程的消息记录到不同的文件中? 我在 SO 上找到了多个答案(例如),但没有一个涵盖在不同文件上调用另一个模块时,他们如何找出他们可以使用的logger

=>所以我面临的问题是因为每个线程都使用相同的底层记录器,当我在一个线程中更改logging.basicConfig的文件路径时,它会影响所有线程和驱动程序的 class,因为它们都是使用它。

=>从线程或驱动程序调用的不同模块的函数如何理解它应该选择哪个记录器?


关于如何使用 Python 使用不同的类和导入动态记录更改文件句柄的评论部分有讨论和推荐的解决方案。

@Martijn 彼得斯:

下一个选项:创建每个线程处理程序,为每个处理程序提供一个过滤器,用于过滤 logrecord thread属性。 将过滤器附加到任何其他为具有thread集的日志记录返回 False 的处理程序

是的,您可以将来自不同线程的日志条目定向到不同的文件。 您需要:

  • 创建一个 日志过滤器,可以通过LogRecord.threadLogRecord.threadName属性过滤记录
  • 创建一个接受具有特定或所有线程 ID 的记录的过滤器。
  • 为每个线程创建一个日志处理程序,为其提供一个日志过滤器,该过滤器只接受其特定线程的日志记录。
  • 将忽略线程日志记录的过滤器附加到任何其他处理程序。

过滤时,您可以选择过滤线程 id(由threading.get_ident()返回的值)或线程名称(无论您作为name参数传递给Thread() object的任何内容)。 如果您的线程名称有一个模式,那么您可以在这里使用它。

创建自定义过滤器很容易:

import threading
from logging import Filter

class ThreadFilter(Filter):
    """Only accept log records from a specific thread or thread name"""

    def __init__(self, threadid=None, threadname=None):
        if threadid is None and threadname is None:
            raise ValueError("Must set at a threadid and/or threadname to filter on")
        self._threadid = threadid
        self._threadname = threadname

    def filter(self, record):
        if self._threadid is not None and record.thread != self._threadid:
            return False
        if self._threadname is not None and record.threadName != self._threadname:
            return False
        return True

class IgnoreThreadsFilter(Filter):
    """Only accepts log records that originated from the main thread"""

    def __init__(self):
        self._main_thread_id = threading.main_thread().ident

    def filter(self, record):
        return record.thread == self._main_thread_id

如果要匹配特定模式,请相应地调整代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM