在由 Docker Compose 管理的 Docker 容器内运行的 Python 应用程序中使用 print()语句时,只记录 sys.stderr输出。香草 print()报表不见了,所以这个:
print()
sys.stderr
print("Hello? Anyone there?")
从来没有出现在日志里:
(您可以在我的应用程序中看到其他库显式打印的其他日志,但不包括我自己的调用。)
如何避免我的 print()呼叫被忽略?
默认情况下,Python 将输出缓冲到 sys.stdout。
sys.stdout
有几种选择:
1. 调用显式 flush
flush
重构原始 print 语句以包含 flush=True关键字,如:
flush=True
print("Hello? Anyone there?", flush=True)
注意: 这将导致 完整的缓冲区刷新,而不仅仅是相同的打印调用。因此,如果其他地方有没有显式解除缓冲的“裸”打印函数调用(即没有 flush=True) ,这些函数也将总是被刷新。
你可以通过以下方式达到同样的效果:
import sys sys.stdout.flush()
这个选项是有用的,如果你想最大限度地控制 什么时候的冲洗将会发生。
2. 通过 PYTHONUNBUFFERED env 变量解压整个应用程序
PYTHONUNBUFFERED
将以下内容放入 docker-compose.yml文件的 environment部分:
docker-compose.yml
environment
PYTHONUNBUFFERED: 1
这将导致立即刷新到 stdout的所有输出。
stdout
3. 用 -u运行 python
-u
与上面的选项 # 2一样,这将导致 Python 在应用程序的整个执行生命周期中“未缓冲”地运行。用 abc 0就行了不用环境变量了。
很简单,如果在 Dockerfile 行中添加选项 -u,它将打印您的日志:
CMD ["python", "-u", "my_python_script.py"]
无需更改环境变量或更改程序的所有 print 语句。
使用 pytest,我的解决方案是添加 -s选项。
pytest
-s
例如,在我的场景中,我还需要打开详细模式,我必须将 pytest -sv。
pytest -sv