为何Docker/Containerd日志的Stream字段始终为stderr?
日志全部标记为stderr的原因分析
核心问题出在容器应用自身的日志输出配置,而非Docker或Containerd这些CRI的问题,具体拆解如下:
应用日志框架默认输出到stderr
很多编程语言的日志工具默认会把所有日志(包括Info、Warning级)都输出到stderr。比如Python的logging模块默认的StreamHandler绑定的是sys.stderr;Java的java.util.logging默认控制台输出也是指向stderr;甚至一些Shell脚本如果没特意指定输出目标,也会默认把信息打到stderr。CRI仅做流的收集,不做日志级别解析
Docker和Containerd作为容器运行时,只会忠实地收集容器进程实际输出的stdout和stderr流,它们没有能力解析日志内容、识别日志级别,更不会主动把Info级日志从stderr转到stdout。只要应用把日志写到了stderr,CRI就会把对应的stream字段标记为stderr,不管日志本身是什么级别。容器启动脚本的重定向问题
如果容器的启动命令或脚本里用了输出重定向(比如command >&2),会把应用原本应该输出到stdout的内容强制转到stderr,导致所有日志都被CRI标记为stderr。
解决方向(补充)
要实现按级别分流日志,得从应用端调整:
- 修改应用的日志框架配置,给不同级别日志指定输出流:比如给Info级日志绑定stdout,Error级绑定stderr。
- 检查容器启动脚本,移除不合理的输出重定向,让应用的原始输出流正常传递给CRI。
内容的提问来源于stack exchange,提问作者magiceses
相关产品推荐
相关产品推荐

