python:打印每个线程的输出,以分隔文件没有进程

时间:2013-11-18 19:39:38

标签: python multithreading logging

我有几个线程,每个线程将输出写入stdout。但是,我想将每个线程的输出重定向到彼此独立的单独文件,然后合并它们以保持每个线程的流动。

我的意思如下:

Thread1将每个打印,每个异常和每个其他输出写入file1.log Thread2将每个打印,每个异常和每个其他输出写入file2.log 等等。 所以我正在寻找的是为每个线程专门设置stdout。但是,设置stdout只能全局工作意味着Thread1和Tread2将始终写入相同的已定义的stdout。我还没有发现如何做到这一点。 我不能使用流程,因为另一个问题。

我该怎么做?

1 个答案:

答案 0 :(得分:7)

Python logging模块是thread-safe

使用它为每个线程创建一个单独的记录器,并将FileHandler注册到(也)记录到文件中:

logger = logging.getLogger('thread-1')
file_handler = logging.FileHandler('thread-1.log')
logger.addHandler(file_handler)

这是一个更完整的例子:

import logging
import random
import threading
import time

NUM_THREADS = 5


def worker(delay, logger):
    """A toy worker function, taking the logger as an argument.
    """
    logger.info("Starting work...")
    for i in range(3):
        logger.info('Sleeping %0.02f', delay)
        time.sleep(delay)
    logger.info('Done.')


for n in range(1, NUM_THREADS + 1):
    # create the thread's logger
    logger = logging.getLogger('thread-%s' % n)
    logger.setLevel(logging.DEBUG)

    # create a file handler writing to a file named after the thread
    file_handler = logging.FileHandler('thread-%s.log' % n)

    # create a custom formatter and register it for the file handler
    formatter = logging.Formatter('(%(threadName)-10s) %(message)s')
    file_handler.setFormatter(formatter)

    # register the file handler for the thread-specific logger
    logger.addHandler(file_handler)

    delay = random.random()
    t = threading.Thread(target=worker, args=(delay, logger))
    t.start()


main_thread = threading.currentThread()
for t in threading.enumerate():
    if t is not main_thread:
        t.join()

这将为您提供五个日志文件,thread-1.logthread-5.log,仅包含相应线程的输出:

<强> thread-1.log

(Thread-1  ) Starting work...
(Thread-1  ) Sleeping 0.53
(Thread-1  ) Sleeping 0.53
(Thread-1  ) Sleeping 0.53
(Thread-1  ) Done.

如果您仍想登录控制台,只需创建StreamHandler并将其附加到记录器:

stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)

默认情况下,这将记录到STDERR。如果您需要STDOUT,请使用

logging.StreamHandler(sys.stdout)

有关使用Python logging模块的更多信息,请参阅Advanced Logging Tutorial