如何使用Django中的并发进程登录单个文件而不使用独占锁

Fer*_*eia 5 python django logging azure

鉴于正在多个服务器上同时执行的Django应用程序,该应用程序如何记录到单个共享日志文件(在网络共享中),而不保持此文件在独占模式下永久打开?

当您想要利用日志流时,这种情况适用于托管在Windows Azure网站上的Django应用程序.

这个示例项目中,我尝试使用ConcurrentLogHandler,如下所示:

settings.py中:

'ConcurrentLogHandler':{
    'level': 'DEBUG',
    'class': 'cloghandler.ConcurrentRotatingFileHandler',
    'formatter': 'verbose',
    'filename': os.getenv('LOGFILE', 'django.log')
},
Run Code Online (Sandbox Code Playgroud)

views.py中:

from time import gmtime, strftime
import logging
from django.http import HttpResponse

logger = logging.getLogger(__name__)

def home(request):
    current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    logger.info('home ' + current_time)
    return HttpResponse("Hello from Django! It is now " + current_time + ".\n")
Run Code Online (Sandbox Code Playgroud)

写入日志,但在网站运行时似乎没有刷新文件.另外,如果我尝试使用FTP读取文件我得到这个消息:"因为它正由另一个进程使用550个进程无法访问文件."

如果我停止应用程序,文件将关闭,我可以读取该文件并查看其中的所有日志.

我假设ConcurrentLogHandler将允许对日志文件的共享访问.这个假设是错的吗?是否需要一些额外的配置?还有其他选择吗?

Vin*_*jip 3

另一种方法是将所有 Django 日志记录发送到队列(例如 Redis 队列,使用类似这样的东西,或 a multiprocessing.Queue),然后单个进程读取队列并将记录写入文件。有更多的移动部件,因此这可能适合也可能不适合您的需求,但它会消除文件争用。有关使用来自多个进程的日志记录的更多选项,请参阅这篇文章。

当然,您也可以设置一个套接字服务器,并使用 aSocketHandler将日志记录事件从所有 Django 进程发送到服务器,然后写入文件。Python 文档包含此类服务器的工作示例。