我有几个线程,每个线程将输出写入stdout。但是,我想将每个线程的输出重定向到彼此独立的单独文件,然后合并它们以保持每个线程的流动。
我的意思如下:
Thread1将每个打印,每个异常和每个其他输出写入file1.log Thread2将每个打印,每个异常和每个其他输出写入file2.log 等等。 所以我正在寻找的是为每个线程专门设置stdout。但是,设置stdout只能全局工作意味着Thread1和Tread2将始终写入相同的已定义的stdout。我还没有发现如何做到这一点。 我不能使用流程,因为另一个问题。
我该怎么做?
答案 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.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.
如果您仍想登录控制台,只需创建StreamHandler
并将其附加到记录器:
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
默认情况下,这将记录到STDERR
。如果您需要STDOUT
,请使用
logging.StreamHandler(sys.stdout)
有关使用Python logging
模块的更多信息,请参阅Advanced Logging Tutorial。