Python:多个进程如何记录到同一文件?

21 投票
3 回答
21939 浏览
提问于 2025-04-17 17:12

Python的logging库是否支持让两个(或更多)独立的Python进程同时记录日志到同一个文件?从我读过的文档来看,这一点似乎不太明确。

如果可以的话,那在完全不同的机器上呢?比如说共享的日志文件存在于一个NFS共享上,两个机器都能访问。

3 个回答

0

最简单的方法是使用自定义的处理程序来记录日志,这样可以把所有来自子进程的日志通过队列传递到主进程,然后在主进程中记录这些日志。这样做的一个例子就是在客户端应用程序中,那里有主界面线程和工作线程。

另外,在POSIX系统上,你可以使用追加模式来记录日志。对于最多4KB的数据,这个过程是原子的,也就是说不会出现数据混乱的情况。

3

解决这个问题的一个简单方法是创建一个日志记录的进程,它在一个套接字上监听,只是把收到的内容输出出来。

关键是利用这个套接字队列作为一种仲裁机制。

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="which port to listen on", type=int)
p.add_argument("-b", "--backlog", help="accept backlog size", type=int)
p.add_argument("-s", "--buffersize", help="recv buffer size", type=int)
args = p.parse_args()

port = args.port if args.port else 1339
backlog = args.backlog if args.backlog else 5
size = args.buffersize if args.buffersize else 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(backlog)
print "Listening on port ", port, 'backlog size', backlog, 'buffer size', size, '\n'
while 1:
    try:
        (client, address) = s.accept()
        data = client.recv(size)
        print data
    except:
        client.close()

接下来进行测试:

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="send port", action='store', default=1339, type=int)
p.add_argument("text", help="text to send")
args = p.parse_args()

if not args.quit and not args.text:
    p.print_help()
else:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', args.port))
        s.send(args.text)
    except:
        s.close()

然后可以这样使用它:

stdbuf -o L ./logger.py -b 10 -s 4096 >>logger.log 2>&1 &

并用以下方式监控最近的活动:

tail -f logger.log

来自任何进程的每一条日志记录都会被原子性地输出。把这个功能加入到标准的日志系统中应该不会太难。使用套接字的好处是多个机器也可以同时向一个专门的机器上的日志发送信息。

25

不,这个功能不被支持。根据Python的日志使用手册

虽然在一个进程中,多个线程同时写日志是安全的,也就是说可以支持多个线程写入同一个文件,但多个进程同时写一个文件是不被支持的。这是因为在Python中,没有标准的方法来让多个进程安全地访问同一个文件。

接下来,手册建议使用一个单独的套接字服务器进程来处理日志,其他进程则把日志信息发送给这个服务器。关于这种方法的具体例子,可以在通过网络发送和接收日志事件的部分找到。

撰写回答