日志库的正确使用姿势

什么是日志

所谓日志(Log)是指系统所指定对象的某些操作和其操作结果按时间有序的集合。log文件就是日志文件,log文件记录了系统和系统的用户之间交互的信息,是自动捕获人与系统终端之间交互的类型、内容或时间的数据收集方法;

日志是用来记录,用户操作,系统状态,错误信息等等内容的文件,是一个软件系统的重要组成部分。一个良好的日志规范,对于系统运行状态的分析,以及线上问题的解决具有重大的意义。

日志规范

在开发软件打印日志时,需要注意一些问题,举例可能不全

  • 重要功能日志尽可能的完善。
  • 不要随意打印无用的日志,过多无用的日志会增加分析日志的难度。
  • 日志要区分等级 如 debug,warn,info,error 等。
  • 捕获到未处理错误时最好打印错误堆栈信息

Go 语言常用的日志库

Go 语言标准库中就为我们提供了一个日志库 log,除了这个以外还有很多日志库,如 logrusgloglogxUberzap 等等,我们今天主要介绍一下zap,文章后面还会使用 zap 实现 kratoslog

fmtloglog

快速使用

log
logstderrlog
log
Print/Printf/PrintlnPanic/Panicf/PaniclnpanicFatal/Fatalf/Fatallnos.Exit(1)
fln
log.Panicfpaniclog.Fatalf

定制

前缀

log.SetPrefixLogin:
log.Prefix

选项

设置选项可在每条输出的文本前增加一些额外信息,如日期时间、文件名等。

log
Ldate2020/02/07Ltime11:45:45LmicrosecondsLtime11:45:45.123123Llongfilegithub.com/darjun/go-daily-lib/log/flag/main.go:50Lshortfilemain.go:50LUTCLdateLtime
log.SetFlag
log.Flags()

运行代码,输出:

2020/02/07 11:56:59.061615 main.go:20: dj login, age:18
log.SetFlag
logLstdflagLdate | Ltime

这就是为什么默认情况下,每条日志前会自动加上日期和时间。

自定义

logLoggerstdlogstd
Logger
log.New
io.WriterWriterprefixlogger.SetPrefixflaglogger.SetFlag
bytes.Bufferbuf

运行代码:

io.Writerio.MultiWriterbytes.Buffer

如果你愿意,还可以发送到到网络。

实现

logOutput
LshortfileLlongfileOuputruntime.Callerruntime.Callercalldepth

一般的调用路径是:

log.Printflog.Printfstd.Output
Outputlog.PrintfcalldepthOutputruntime.Callerlog.Printfstd.Outputlog.Printf
formatHeader
Writer

这里有两个优化技巧:

runtime.Callerlogger[]bytebufbufWriter

参考

log官方文档