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

use*_*882 0 python logging multithreading

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

我的意思是:

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

我怎样才能做到这一点?

Luk*_*raf 7

Python logging模块是线程安全的.

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

logger = logging.getLogger('thread-1')
file_handler = logging.FileHandler('thread-1.log')
logger.addHandler(file_handler)
Run Code Online (Sandbox Code Playgroud)

这是一个更完整的例子:

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()
Run Code Online (Sandbox Code Playgroud)

这会给你五个日志文件,thread-1.log通过thread-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.
Run Code Online (Sandbox Code Playgroud)

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

stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
Run Code Online (Sandbox Code Playgroud)

这将STDERR默认登录.如果你愿意STDOUT,请使用

logging.StreamHandler(sys.stdout)
Run Code Online (Sandbox Code Playgroud)

有关使用Python logging模块的更多信息,请参阅高级日志教程.