【问题标题】:docker-compose not printing stdout in Python appdocker-compose 不在 Python 应用程序中打印标准输出
【发布时间】:2018-12-24 00:34:54
【问题描述】:

在由 Docker Compose 管理的 Docker 容器内运行的 Python 应用程序中使用 print() 语句时,仅记录 sys.stderr 输出。没有看到香草print() 语句,所以这个:

print("Hello? Anyone there?")

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

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

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

【问题讨论】:

    标签: python docker docker-compose


    【解决方案1】:

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

    有几个选项:

    1.调用明确的flush

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

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

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

    您可以通过以下方式实现相同的目标:

    import sys
    sys.stdout.flush()
    

    如果您想要最大程度地控制何时刷新将发生,则此选项很有用。

    2。通过PYTHONUNBUFFERED env var 解除整个应用程序的缓冲

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

    PYTHONUNBUFFERED: 1

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

    3.使用-u运行python

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

    【讨论】:

    • 只有 flush=True 有效。 Windows 10、泊坞窗桌面、Python 3.7
    • @TDiddy - 当我写这篇文章时,它在 2018 年 7 月 16 日有效。我对未来不做任何保证。
    • 在 docker 中运行一个应用程序给人的印象是应用程序没有运行......在查看其他服务器日志时,我们看到连接到来......所以问题主要是缓冲区......这是惊人的!谢谢!
    • 对于第二种解决方案,似乎是 docker 更改了环境变量的语法。 ``` - PYTHONUNBUFFERED=1``` 为我工作
    【解决方案2】:

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

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

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

    【讨论】:

    • -y 是无效标志。 -u 是正确的(我会在上面的答案中添加它。)
    • 不适用于 Python 3.7、windows 10、docker-desktop
    【解决方案3】:

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

    例如,在我还需要详细模式的情况下,我必须输入pytest -sv

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2022-11-26
      • 2012-09-29
      相关资源
      最近更新 更多