如何让Supervisord实时输出Python程序日志无需停止服务?
我之前也踩过这个坑!虽然你在Python代码里加了sys.stdout.flush(),但Supervisord和Python的双重缓冲机制还是会把日志攒到服务停止才一次性写入文件。下面几个方法可以帮你实现实时日志输出:
1. 给Python进程设置无缓冲环境变量
这是最直接有效的解决方案,直接让Python跳过自身的输出缓冲。在你的Supervisord程序配置文件(通常在/etc/supervisor/conf.d/my-project.conf)里,给[program:my-project]段添加environment配置:
[program:my-project] command=python /path/to/your/script.py directory=/path/to/your/project stdout_logfile=/var/log/supervisor/my-project.log stderr_logfile=/var/log/supervisor/my-project.err.log # 关键配置:禁用Python输出缓冲 environment=PYTHONUNBUFFERED=1 redirect_stderr=true
设置PYTHONUNBUFFERED=1后,Python会把stdout和stderr的内容直接输出,不再做缓冲,这样日志会实时写到Supervisord指定的日志文件里,甚至不需要你手动调用sys.stdout.flush()。
2. 关闭Supervisord的捕获缓冲
有时候Supervisord自身会对捕获到的子进程输出做缓冲,默认攒够1KB才写入文件。你可以在程序配置里禁用这个缓冲:
[program:my-project] # 其他配置... # 禁用stdout和stderr的捕获缓冲 stdout_capture_maxbytes=0 stderr_capture_maxbytes=0
这个参数控制Supervisord临时存储子进程输出的缓冲区大小,设为0就会实时把捕获到的内容写入日志文件。
3. 检查Python脚本的输出格式
确保你的print语句是以换行结尾的(Python2里print "xxx"默认会加换行,没问题),如果是用sys.stdout.write()输出,记得加上换行符\n,否则即使关闭了缓冲,部分日志系统也会等待换行才输出内容。
把这些配置调整完后,重启Supervisord(supervisorctl reload),再启动你的项目,就能看到日志实时写入文件了!
内容的提问来源于stack exchange,提问作者Blurry Script

