内容简介:Kubernetes 中使用的 klog 其实就是klog 包是一个提供了 INFO/ERROR/V 日志记录的模块。它提供了函数 Info、Warning、Error、Fatel,以及诸如 Infof 的格式化版本。它还提供了由 -v 和 -vmodule=file=2 标志控制的 V-style 日志。
Kubernetes 中使用的 klog 其实就是 glog 。这里简要地介绍一下它的功能及实现。
功能简介
klog 包是一个提供了 INFO/ERROR/V 日志记录的模块。它提供了函数 Info、Warning、Error、Fatel,以及诸如 Infof 的格式化版本。它还提供了由 -v 和 -vmodule=file=2 标志控制的 V-style 日志。
日志先写到缓冲区中,并且周期性的使用 Flush 写入到文件中。程序在退出之前会调用 Flush 以保证写入所有日志。
日志分 INFO、WARNING、ERROR 和 FATAL 这四个等级,它们的严重等级依次递增,默认等级为 ERROR。写入到高严重等级日志文件的消息也会被写入到所有严重等级比它低的日志文件中。
执行过程
1.主要结构 loggingT
klog 使用了一个全局的 loggingT 变量 logging。
freeList:是一个缓冲区链表,日志会先写入到这里面,加上日志头拼接好,然后写入到 syncBuffer 的 *bufio.Writer。
file:是用于储存日志的文件,syncBuffer 是真正有用的结构。*bufio.Writer 用于缓存日志数据,缓冲区大小初始 256k。缓冲区每隔 30 秒向文件写入一次。文件大小最大 1800M,超过 1800M 会创建新的文件。
2.文件同步过程
flushDaemon:init() 函数会设置默认的日志严重等级以及 V-log 等级,然后启动 flushDaemon。每间隔 30s 刷新所有日志并尝试将其数据同步到磁盘。日志会按照严重等级递减的顺序来刷新和同步,此做法是为了保证出现错误尽量小地影响严重等级高的日志。
3.写入日志过程
l.getBuffer() 与 buf.Write(…):从 l.freeList
中获取到 buf 后,会按顺序写入日志头以及日志信息。日志格式如下:
0 1 2 |3 4 012345678901234567890123456789|01234567890 Lmmdd hh:mm:ss.uuuuuu _______ |file:line] msg... threadid 前 29 字节固定,file 和 line 不定长。 L 表示日志级别,有 "IWEF"(例如,"I" 表示 INFO) mm 月份(零填充,例如五月是 "05") dd 日期(零填充) hh:mm:ss.uuuuuu 以小时、分钟、微秒表示的时间 threadid 本应该为线程 ID,但只能获取到进程 ID file 文件名 line 行号(零填充) msg 用户提供的信息
syncBuffer.Write(data):将日志从 buf 写入到 syncBuffer 的 buffer 中。日志等级为 fatal 时,刷新并同步(超时时间 10s)所有日志并退出。
l.putBuffer(buf):将 buf 放回 l.freeList
,如果 buf 中的 bytes.Buffer 大小超过 256 字节,就等待 GC 回收。
部分代码细节
1.freeList 的操作
func (l *loggingT) getBuffer() *buffer { l.freeListMu.Lock() b := l.freeList if b != nil { l.freeList = b.next } l.freeListMu.Unlock() if b == nil { b = new(buffer) } else { b.next = nil b.Reset() } return b } func (l *loggingT) putBuffer(b *buffer) { if b.Len() >= 256 { return } l.freeListMu.Lock() b.next = l.freeList l.freeList = b l.freeListMu.Unlock() }
2.高严重等级的日志也将写入到低严重等级的日志文件中。
switch s { case fatalLog: l.file[fatalLog].Write(data) fallthrough case errorLog: l.file[errorLog].Write(data) fallthrough case warningLog: l.file[warningLog].Write(data) fallthrough case infoLog: l.file[infoLog].Write(data) }
3.rotateFile 创建新文件时使用符号链接( klog_file.go
)
for _, dir := range logDirs { fname := filepath.Join(dir, name) f, err := os.Create(fname) if err == nil { symlink := filepath.Join(dir, link) os.Remove(symlink) os.Symlink(name, symlink) return f, fname, nil } lastErr = err }
以上所述就是小编给大家介绍的《klog 源码分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
大学程序设计课程与竞赛训练教材
吴永辉、王建德 / 机械工业出版社 / 2013-6 / 69.00
本书每章为一个主题,实验内容安排紧扣大学算法和数学的教学,用程序设计竞赛中的算法和数学试题作为实验试题,将算法和数学的教学与程序设计竞赛的解题训练结合在一起;在思维方式和解题策略的训练方面,以问题驱动和启发式引导为主要方式,培养读者通过编程解决问题的能力。 本书特点: 书中给出的234道试题全部精选自ACM国际大学生程序设计竞赛的世界总决赛以及各大洲赛区现场赛和网络预赛、大学程序设计竞......一起来看看 《大学程序设计课程与竞赛训练教材》 这本书的介绍吧!