我有一个在Django中运行的网站。前端是lighttpd,正在使用fcgi来托管django。

我按如下方式启动我的fcgi进程:

python2.6 /<snip>/manage.py runfcgi maxrequests=10 host=127.0.0.1 port=8000 pidfile=django.pid

对于日志记录,我有一个RotatingFileHandler定义如下:

file_handler = RotatingFileHandler(filename, maxBytes=10*1024*1024, backupCount=5,encoding='utf-8')

日志记录正在运行。但是,当它们甚至没有达到10Kb时,看起来文件正在旋转,更不用说10Mb了。我的猜测是每个fcgi实例只处理10个请求,然后重新生成。每个重生的fcgi都会创建一个新文件。我确认fcgi经常在新的进程ID下启动(很难准确地说出时间,但不到一分钟)。

有没有办法解决这个问题?我希望所有fcgi实例都记录到一个文件,直到它达到大小限制,此时将发生日志文件轮换。

有帮助吗?

解决方案

正如Alex所说,日志记录是线程安全的,但标准处理程序无法安全地用于从多个进程登录到单个文件中。

ConcurrentLogHandler 使用文件锁定来允许从多个进程内进行日志记录。 / p>

其他提示

在你的鞋子里,我会切换到 TimedRotatingFileHandler - - 我很惊讶基于大小的旋转文件句柄给出了这个问题(因为它应该不知道哪些进程产生了日志条目),但是定时版本(虽然不是完全依赖于您喜欢的参数)应该解决它。或者,编写您自己的,更加可靠的旋转文件处理程序(您可以从标准库源中获取很多)确保不同的进程不是问题(因为它们永远不应该)。

当你似乎使用默认文件打开模式append(“a”)而不是write(“w”)时,如果一个进程重新生成它应该附加到现有文件,然后翻转时达到了大小限制。因此,我不确定您所看到的是由重新生成的CGI流程引起的。 (这当然假设当进程重新生成时文件名保持不变)。

虽然日志包是线程安全的,但它不处理来自多个进程的同一文件的并发访问 - 因为在stdlib中没有标准的方法来执行它。我的正常建议是设置一个单独的守护进程,该进程实现套接字服务器并将通过它接收的事件记录到文件中 - 其他进程然后只实现一个SocketHandler与日志记录守护进程通信。然后所有事件将被正确序列化到磁盘。 Python文档包含工作套接字服务器可以作为满足这种需求的基础。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top