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