解决django日志多进程写入混乱的问题

用过django自带日志配置的人都知道logging.handlers.RotatingFileHandler功能,但是最近在项目中发现,如果uwsgi配置django启动多进程的话,即便是开启了日志滚动功能,也不能保证所有日志都会写入当前最新的日志中,这究竟是为什么呢?
让我们看看下面的实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#coding=utf-8
import os
import time
import multiprocessing

f = open("./1.log","a")
def write():
while True:
f.write("Hello World\n",)
f.flush()
print("write line")
time.sleep(2)
if __name__=='__main__':
p = multiprocessing.Process(target=write)
p.start()

执行脚本后我们可以看到在1.log中会有持续写入

1
2
3
4
5
# tail -f 1.log 
Hello World
Hello World
Hello World
Hello World

此时我们把1.log改名

1
2
3
4
5
# mv 1.log 2.log
# tail -f 2.log
Hello World
Hello World
Hello World

会发现2.log仍然会继续写入,因为进程得到了文件的句柄,所以就算这个文件改名为2.log了,它也会继续往2这个文件写入的。
这也就解释了为什么即使配置了
logging.handlers.RotatingFileHandler或者logging.handlers.TimedRotatingFileHandler,文件配置了切片也会写到每个进程对应的文件下面。

幸好已经有解决这个问题的模块

使用以上两个模块都可以解决问题