【问题标题】:Python INFO logs going to stderr_logfile of supervisordPython INFO 日志将转到 supervisord 的 stderr_logfile
【发布时间】:2025-12-06 18:20:03
【问题描述】:

我有一个已配置为通过 Supevisord 运行的 python 烧瓶应用程序。 supervisor.conf 文件看起来像这样 -

[inet_http_server]
port=127.0.0.1:9001     

[supervisord]
logfile=/path/to/log/supervisord.log  
logfile_maxbytes=0                          ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=0                           ; # of main logfile backups; 0 means none, default 10
loglevel=debug                              ; log level; default info; others: debug,warn,trace
pidfile=/path/to/supervisord.pid 
nodaemon=false                              ; start in foreground if true; default false
directory=/path/to/project

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

; The supervisorctl section configures how supervisorctl will connect to
; supervisord.  configure it match the settings in either the unix_http_server
; or inet_http_server section.

[supervisorctl]
serverurl=http://127.0.0.1:9001   
history_file=/path/to/.sc_history  ; use readline history if available

[program:my_server]
command=<command to run the program>
directory=/path/to/project
stdout_logfile=/path/to/log/%(program_name)s_stdout.log       ; stdout log path, NONE for none; default AUTO
stdout_logfile_maxbytes=0  ; 
stderr_logfile=/path/to/log/%(program_name)s_stderr.log       ; stderr log path, NONE for none; default AUTO
stderr_logfile_backups=0     ; # of stderr logfile backups (0 means none, default 10)

问题是,当我通过 supervisord 运行应用程序时,它会将所有输出 - 信息、调试、错误等记录到 %(program_name)s_stderr.log 日志文件而不是 %(program_name)s_stdout.log 文件中。

我使用 python 的默认日志库将我的信息消息记录为 -

logger.info("Some info msg")

这种行为的原因可能是什么?

【问题讨论】:

标签: python flask logging supervisord


【解决方案1】:

虽然这个问题是用 flask 和 supervisord 标记的,但核心问题实际上是 python 的“日志记录”系统是如何工作的。默认情况下,logger.info() 消息被发送到标准错误,而不是标准输出,所以烧瓶和主管正在做他们被告知的事情(真的烧瓶几乎没有进入它)。

python/logger 部分在这里有一个很好的答案:Logging, StreamHandler and standard streams

简而言之,你必须为 stderr 和 stdout 创建一个单独的 StreamHandler,并告诉它们哪些消息(INFO、DEBUG、ERROR 等)发送到哪些消息。

在接受的答案中有工作代码,所以我不会在这里重复。

【讨论】: