klog bug:仅输出到日志文件,不打印到命令行/stderr

一、 问题描述

开发k8s插件,使用klog作为日志工具,开发完成发现在设置将日志打印到文件后,Error级别的日志信息仍然会输出到命令行,过多日志打印会使后期将服务部署于docker有卡死的风险(docker的bug,日志输出过快会卡顿)

二、解决思路

1. 先看命令行参数

在这里插入图片描述
可以看到klog的配置还是很灵活的,根据提示尝试了以下启动参数:
1. go run main.go -log_dir=logs -logtostderr=false
2. go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=false
3. go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=true -stderrthreshold=5
4. go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=true -stderrthreshold=0
5. go run main.go -log_dir=logs -logtostderr=false -v=0
6. go run main.go -log_dir=logs -logtostderr=false -v=5
不管根据flag参数怎么调试,Error日志始终会打印到命令行,于是怀疑logtostderr或alsologtostderr参数在klog项目中应该存在bug;

2. 查找bug

先查看alsologtostderr,
在这里插入图片描述

在这里插入图片描述
发现这里有个if,在这个条件下如果alsoToStderr或l.alsoToStderr为true或s >= l.stderrThreshold.get()都会出现把日志打印到命令行的问题:

  1. 那我们把alsoToStderr设置为false,
  2. 再加上一句输出看看参数:fmt.Printf("666666 %v : %v : %v : %v", alsoToStderr, l.alsoToStderr, s ,l.stderrThreshold.get())
  3. 执行go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=false
  4. 输出为666666 false : false : 2 : 2,
  5. 这样看那应该是s >= l.stderrThreshold.get()导致的error日志输出到命令行,这里不知道s为啥为2,我们尝试把stderrThreshold设置>2,
  6. 执行go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=false -stderrthreshold=3
  7. 打印666666 false : false : 2 : 3,同时error日志也不再打印到命令行,并且日志文件里是有error日志的

3. 追查原因

为什么s一直2?向上追查代码调用发现:
在这里插入图片描述
在这里插入图片描述
这次水落石出了,stderrthreshold默认为2,而Error日志的值为2,正常情况下logLevel >= stderrthreshold的都会被输出,即默认情况下Errorlog以上的等级都会被输出,这就是为啥Infolog不会被输出到命令行,error会的原因

4. 问题原因

真正导致我们一直走弯路的是官方的文档和代码中的参数注解:
"stderrthreshold" : "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false ")

从官方给的解释来看,要stderrthreshold生效就必须让logtostderr=falsealsologtostderr=true,因此我们上面的flag参数尝试一直保持这种设置,但是代码里的实现确是:要想stderrthreshold生效就必须让logtostderr=falsealsologtostderr=false才行,这里官方的alsologtostderr与stderrthreshold意义冲突了,应该是个bug

三、总结

被官方坑了一道,浪费了不少时间
总之,要想让klog日志输出到日志文件,且不输出到命令行的,参数配置为:
go run main.go -log_dir=logs -logtostderr=false -alsologtostderr=false -stderrthreshold=3
其中-stderrthreshold的大小看你自己的需求设定在这里插入图片描述
想要全部都不输出,就设定为4即可

后续:

给官方提了issue,官方确认为bug:
在这里插入图片描述

参考资料:
  1. https://pkg.go.dev/k8s.io/klog
  2. https://github.com/kubernetes/klog
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

THMAIL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值