标准日志库 log
Go标准库中有log包,提供了简单的日志功能。
输出 | 格式输出 | 换行输出 | |
---|---|---|---|
log.Print() | log.Printf() | log.Println() | 类似fmt.Print* |
log.Fatal() | log.Fatalf() | log.Fatalln() | 相当于log.Print* + os.Exit(1) |
log.Panic() | log.Panicf() | log.Panicln | 相当于log.Print* + panic() |
日志输出需要使用日志记录器Logger。
log包提供了一个缺省的Logger即std。std是小写的,包外不可见,所以提供了Default()方法返回std给包外使用。
1 | // 大约在源码log.go第90行 |
上表列出的方法底层都使用std.Output输出日志内容。而std本质上是使用了标准错误输出、无前缀、LstdFlags标准标记的记录器Logger实例。
std使用
1 | func main() { |
自定义Logger
1 | type Logger struct { |
如果觉得缺省Logger std不满意,可以New构建一个自定义Logger并指定前缀、Flags。
1 | func main() { |
写日志文件
New方法签名 New(out io.Writer, prefix string, flag int) *Logger 中out参数提供Writer接口即可,那么就可以提供一个可写文件对象。
1 | package main |
第三方日志库 zerolog
log模块太简陋了,实际使用并不方便。
logrus有日志级别、Hook机制、日志格式输出,很好用;
zap是Uber的开源高性能日志库;
zerolog更注重开发体验,高性能、有日志级别、链式API,json格式日志记录,号称0内存分配。
1 | 安装 go get -u github.com/rs/zerolog/log |
缺省Logger
1 | package main |
log.Print()、log.Printf()方法使用方式和标准库log模块类似。
日志级别
zerolog提供以下级别(从高到底)
panic (zerolog.PanicLevel, 5)
fatal (zerolog.FatalLevel, 4)
error (zerolog.ErrorLevel, 3)
warn (zerolog.WarnLevel, 2)
info (zerolog.InfoLevel, 1)
debug (zerolog.DebugLevel, 0)
trace (zerolog.TraceLevel, -1)
级别有
gLevel全局级别
- zerolog.SetGlobalLevel(级别数字或常量) 来设置全局级别
- zerolog.GlobalLevel() 获取当前全局级别
每个Logger的级别
消息的级别
1 | package main |
可以看到,使用缺省logger,全部可以输出日志消息,而log1使22行、23行输出了日志,为什么?
因为,有消息级别和Logger级别。
log1的级别为warn 2,而log1.Debug()输出的消息级别为debug级别0,消息级别 < log1级别,所以消息不能输出。log1.Warn()、log1.Error()产生warn、error消息消息,消息级别 ≥ log1级别,因此可以输出。
而缺省Logger的级别是trace,任何消息级别都大于等于log1的级别,因此都可以输出。
下面调高全局级别,试试看。
1 | package main |
缺省logger和log1都只有error级别的输出,说明将gLevel调整到error级别后,所有logger输出消息都必须大于等于gLevel。
特别注意,zerolog.SetGlobalLevel()
设置的是全局变量gLevel,它影响所有Logger。
日志消息是否能够输出,应当满足下面的要求 消息级别 ≥ max(gLevel, 当前logger级别)
1 | zerolog.SetGlobalLevel(zerolog.Disabled) |
上下文
zerolog是以Json对象格式输出的,还可以自定义一些键值对字段增加到上下文中以输出。
1 | zerolog.SetGlobalLevel(zerolog.InfoLevel) |
错误日志
1 | package main |
全局Logger
1 | // 全局Logger定义如下,可以覆盖全局Logger |
自定义Logger
1 | package main |
写日志文件
1 | package main |
如果只输出到文件可以使用 zerolog.New(f).With().Timestamp().Logger()