Python子进程logging config在Win和Linux下表现不一致的问题

Python父进程通过logging.basicConfig,设定日志文件的路径,子进程再次通过basicConfig设定另一个新的路径。这个操作,在Windows系统和Linux下表现不一致。

区别在于,Windows下将打开不同的文件句柄,写入2个不同的文件 。而在Linux下,则config看起来无效,子进程和父进程使用同一个文件描述符,第二次config无效。(解决的方法文末补充)

import logging
import os
import multiprocessing
import threading

cwd = os.getcwd()


def set_log(log_file_path):
    logging.basicConfig(filename=log_file_path,
                        filemode='a+',
                        format='%(message)s',
                        level=logging.INFO)
    logging.info('%s:  %s' % (logging.root, log_file_path) )


def test_func():
    set_log(os.path.join(cwd, 'test2.log'))


class TestThread(threading.Thread):
    def __init__(self):
        p = multiprocessing.Process(target=test_func)
        p.start()


if __name__ == '__main__':
    set_log(os.path.join(cwd, 'test.log'))
    TestThread()

这个程序在Windows的执行结果是

logging.RootLogger object at 0x0000000002610C18>:  C:\test\test.log
logging.RootLogger object at 0x000000000276C7B8>:  C:\test\test2.log

可以看到,日志写入了两个不同的文件。并且Logger ID不一样

在Linux下的执行结果是

[root@cyberivy-web-dev002-whdx test]# ls *.log
test.log
[root@cyberivy-web-dev002-whdx test]# cat test.log 
:  /root/test/test.log
:  /root/test/test2.log

两个进程的日志都写到了test.log中。 并且 Logger ID 和 fd是一样的

解决的办法

子进程在set_log之前,先 reload(logging), test_func变成

def test_func():
    reload(logging)
    set_log(os.path.join(cwd, 'test2.log'))

修改之后,在Linux执行,日志同样会写入不同的文件

[root@cyberivy-web-dev002-whdx test]# ls *.log
test2.log  test.log
[root@cyberivy-web-dev002-whdx test]# cat *.log
logging.RootLogger object at 0x1df28d0>:  /root/test/test2.log
logging.RootLogger object at 0x1d80bd0>:  /root/test/test.log

发表评论

您的电子邮箱地址不会被公开。