一、 问题描述

开发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
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐