在uWsgi环境中从python工作进程记录到文件

2024-09-30 20:34:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个使用Docker compose部署的Flask应用程序,附带一个小DB和一个uWsgi前端。我希望将flask应用程序的某些输出写入特定的日志文件。其想法是,在午夜,我希望日志文件旋转到第二天,同时保留前X天的备份。我已经在应用程序首次启动时配置了日志文件,如下所示:

handler = TimedCompressedRotatingFileHandler('/home/root/custom_logs/no_RS_queries_planner_api.log',
                                             when="midnight", encoding='utf8', backupCount=14)

logger = logging.getLogger('query_logger')
logger.addHandler(handler)
handler.suffix = "%Y-%m-%d"

# the all-important app variable:
application = Flask(__name__)

#sample log
logger.warning(value1,value2,value3)

当我在我的机器上本地测试Flask应用程序时,这就起作用了,因为运行它只使用一个进程。但如果我尝试使用定义了多个工作进程的uWsgi部署它

; app.ini

[uwsgi]
protocol = uwsgi

chdir=/app/app/

; This is the name of our Python file
; minus the file extension
module = main

; This is the name of the variable
; in our script that will be called
callable = application

master = true;

; Set uWSGI to start up x workers
processes = 9

; We use the port 5000 which we will
; then expose on our Dockerfile
socket = 0.0.0.0:5000
vacuum = trued

die-on-term = true

所有工作进程在午夜对同一个文件进行滚动。实际上是多次覆盖,导致日志文件丢失。这似乎仍然是此类部署中的一个当前问题,并且很难尝试解决。有没有什么简单的方法来处理这种事情而不必大规模地重新构建我的应用程序

作为参考,TimedCompressedRotatingFileHandler是对取自here的现有日志循环类的修改。我尝试了一些大胆的方法,比如尝试获取uWsgi工作者ID并将其作为附加后缀附加到日志文件中,但这似乎不起作用,只输出0。我可以尝试登录到DB并在午夜按计划输出,但我更愿意先尝试登录方法

有谁能帮我找到一个快速解决我烦恼的方法吗


Tags: 文件the方法nameapp应用程序flaskdb
1条回答
网友
1楼 · 发布于 2024-09-30 20:34:04

正确的解决方案是described in the cookbook,尽管情况稍有不同-使用multiprocessing的多个进程:

Although logging is thread-safe, and logging to a single file from multiple threads in a single process is supported, logging to a single file from multiple processes is not supported, because there is no standard way to serialize access to a single file across multiple processes in Python.

当然,在您的情况下,问题不仅在于从多个进程写入日志文件,还在于从多个进程滚动相同的文件

针对您的场景的一个解决方案是:

  1. 所有uWSGI工作程序都应使用日志记录配置,该配置不直接使用文件处理程序,而是使用SocketHandler跨套接字(TCP/IP套接字或Unix域套接字,如果可用)发送记录的事件
  2. 您应该有一个单独的进程,它监听这个套接字,并通过将从它接收到的日志事件记录到文件处理程序来处理这些事件

这种方法将文件写入和滚动保持在一个进程中,因此您描述的问题不应该发生。烹饪书还包含使用SocketHandler通过网络发送日志事件的an example。您应该能够根据侦听器进程调整那里的代码,而不会有太多麻烦

相关问题 更多 >