内容简介: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使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
正则表达式必知必会
Ben Forta / 杨涛、王建桥、杨晓云 / 人民邮电出版社 / 2007 / 29.00元
正则表达式是一种威力无比强大的武器,几乎在所有的程序设计语言里和计算机平台上都可以用它来完成各种复杂的文本处理工作。本书从简单的文本匹配开始,循序渐进地介绍了很多复杂内容,其中包括回溯引用、条件性求值和前后查找,等等。每章都为读者准备了许多简明又实用的示例,有助于全面、系统、快速掌握正则表达式,并运用它们去解决实际问题。 本书适合各种语言和平台的开发人员。一起来看看 《正则表达式必知必会》 这本书的介绍吧!