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

Lee*_*son 21 python docker docker-compose

print()由Docker Compose管理的Docker容器中运行的Python应用程序中使用语句时,仅sys.stderr记录输出。print()没有看到Vanilla 语句,因此:

print("Hello? Anyone there?")
Run Code Online (Sandbox Code Playgroud)

...永远不会出现在常规日志中:

在此处输入图片说明

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

如何避免我的print()电话被忽略?

Lee*_*son 28

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

有几种选择:

1.调用显式 flush

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

print("Hello? Anyone there?", flush=True)
Run Code Online (Sandbox Code Playgroud)

注意:这将导致整个缓冲区刷新,而不仅仅是同一打印调用。因此,如果在其他地方(即没有flush=True)存在未明确取消缓冲的“裸”打印功能调用,则这些调用也将始终被刷新。

您可以使用以下方法实现相同的目的:

import sys
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

如果您希望最大程度地控制何时进行刷新,则此选项很有用。

2.通过PYTHONUNBUFFEREDenv var解缓冲整个应用程序

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

PYTHONUNBUFFERED: 1

这将导致stdout立即清除所有输出。

3.使用以下命令运行python -u

像上面的选项2一样,这将导致Python在应用程序的整个执行生命周期内“无缓冲”运行。只需运行python -u <entrypoint.py>-不需要环境变量。

  • 只有flush=True有效。Windows 10、docker 桌面、Python 3.7 (3认同)
  • 对于第二个解决方案,似乎是 docker 更改了环境变量的语法。`` - PYTHONUNBUFFERED=1``` 为我工作 (3认同)
  • 在 docker 中运行 ap 给人的印象是应用程序没有运行...在查看其他服务器日志时,我们看到连接即将到来...所以问题主要是缓冲区...这太棒了!谢谢你! (2认同)

Ign*_*ier 10

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

CMD ['python', '-u', 'my_python_script.py']
Run Code Online (Sandbox Code Playgroud)

  • -y是无效的标志。-u是正确的(我将其添加到上面的答案中。) (2认同)

And*_*rea 6

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

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