点击上方蓝色“ Go语言中文网 ”关注我们, 领全套Go资料 ,每天学习 Go 语言
编者按:本文实现的简单日志库不一定适合你,但可能会给你一些启发、借鉴
前言
一个完整的日志库不仅仅涵盖日志记录功能,还要包括日志 level、行号、文件切分,甚至包含统计与分析等,Go 语言中的日志库也是很多,其中知名度比较高的有:
库名 | star |
---|---|
logrus[1] | 14940 |
zap[2] | 9827 |
zerolog[3] | 3386 |
seelog[4] | 1464 |
备注:star 数获取时间为 2020-05-28 23:26:00
一千个人有一千个需求,不管是哪个开源日志库,用着总有不顺手的时候,没关系,那就自己实现一个吧,相信自己,来,就让咱们先从实现简单的日志记录功能开始吧~「手动狗头」
思路
功能设计
根据自己的需求,我想要的日志记录功能有:
- 按照 level 输出日志
- 能够同时输出到文件和控制台
- 控制台能够根据 level 将内容输出为不同颜色
- 日志文件根据大小进行分割
- 输出行号
API 设计
一般来说,根据 level 不同,设计有不同的 API,level 大概可以分为: trace、warn、error、fatal, 也就是说对外的 API 可以概括为: T(...inter), W(...), E(...), F(...)
type logger interface{
T(format string, v ...interface{})
W(format string, v ...interface{})
E(format string, v ...interface{})
F(format string, v ...interface{})
}
结构设计
根据需求,日志记录器 logger 的结构需要包含 writers、文件名、文件保存路径、文件分割大小 完整结构设计如下:
type myLog struct {
sync.Once
sync.Mutex //用于outs并发访问
outs map[logType]io.Writer //writer集合
file *os.File //文件句柄
fileName string //日志名
dir string //日志存放路径
size int64 //单个日志文件的大小限制
}
关键方法实现
- 日志文件大小检测
func (m *myLog) checkLogSize() {
if m.file == nil