【Problem】Python 日志输出刷新不及时
编辑
29
2021-01-17
问题描述
FROM python:3
ADD . /code
WORKDIR /code
RUN pip3 install -r requirements.txt -i https://pypi.douban.com/simple
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
CMD python scheduler.py
Dockerfile 如上,发现容器正常运行,但是执行docker logs xx没有日志输出
截图
...
解决方案
原因:
Python 的
stdout
缓冲,只有总量达到 「4k」后才会全部打印出来(Pycharm蔽了这种缓冲,所以在 Pycharm 中调试时并不会发现这样的问题)
使用
-u
命令行开关python -u scheduler.py
-u
可能的不适用情况:不适用于已编译的字节码或以__main__.py
文件为入口点的应用程序方案 2 和方案 5 可以避免这种情况
包装
sys.stdout
每次写入后刷新的对象import functools print = functools.partial(print, flush=True)
设置环境
PYTHONUNBUFFERED
变量class Unbuffered(object): def __init__(self, stream): self.stream = stream def write(self, data): self.stream.write(data) self.stream.flush() def writelines(self, datas): self.stream.writelines(datas) self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) import sys sys.stdout = Unbuffered(sys.stdout) print 'Hello'<br> # 原始sys.stdout仍可作为sys.__ stdout__获得
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
import io, os, sys try: # Python 3, open as binary, then wrap in a TextIOWrapper with write-through. sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True) # If flushing on newlines is sufficient, as of 3.7 you can instead just call: # sys.stdout.reconfigure(line_buffering=True) except TypeError: # Python 2 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
使用需要立刻输出的日志的地方,给
print
添加flush=True
参数(类似于2)print('right', flush=True) # python 3.3版本以上生效
关于此问题的一些讨论:
- 0
- 0
-
赞助
微信 -
分享