Docker-在 Python 应用程序中不打印标准输出

在由 Docker Compose 管理的 Docker 容器内运行的 Python 应用程序中使用 print()语句时,只记录 sys.stderr输出。香草 print()报表不见了,所以这个:

print("Hello? Anyone there?")

从来没有出现在日志里:

enter image description here

(您可以在我的应用程序中看到其他库显式打印的其他日志,但不包括我自己的调用。)

如何避免我的 print()呼叫被忽略?

37297 次浏览

默认情况下,Python 将输出缓冲到 sys.stdout

有几种选择:

1. 调用显式 flush

重构原始 print 语句以包含 flush=True关键字,如:

print("Hello? Anyone there?", flush=True)

注意: 这将导致 完整的缓冲区刷新,而不仅仅是相同的打印调用。因此,如果其他地方有没有显式解除缓冲的“裸”打印函数调用(即没有 flush=True) ,这些函数也将总是被刷新。

你可以通过以下方式达到同样的效果:

import sys
sys.stdout.flush()

这个选项是有用的,如果你想最大限度地控制 什么时候的冲洗将会发生。

2. 通过 PYTHONUNBUFFERED env 变量解压整个应用程序

将以下内容放入 docker-compose.yml文件的 environment部分:

PYTHONUNBUFFERED: 1

这将导致立即刷新到 stdout的所有输出。

3. 用 -u运行 python

与上面的选项 # 2一样,这将导致 Python 在应用程序的整个执行生命周期中“未缓冲”地运行。用 abc 0就行了不用环境变量了。

很简单,如果在 Dockerfile 行中添加选项 -u,它将打印您的日志:

CMD ["python", "-u", "my_python_script.py"]

无需更改环境变量或更改程序的所有 print 语句。

使用 pytest,我的解决方案是添加 -s选项。

例如,在我的场景中,我还需要打开详细模式,我必须将 pytest -sv