为什么要用zap来写日志

原来是写PHP的,一贯用的error_log,第一次写Go项目的时候,还真不知道该怎么写日志,后来就按照PHP的写法自己不成规范的捣鼓写。
去了新公司之后,创造用的是zap。
后来查询 理解了下zap,前同事反应他们很多大公司都在利用zap写日志,GitHub上star 高达7K多,足以解释它受欢迎的程度。

1.zap是Uber开源的日志库;2.很多大的公司和小的公司都在利用;3.跟seelog、logrus等类库比较,高性能是它最突出的上风;我想以上几个缘故原由就已经解释了它的广泛性、稳定性,就值得我们去考试测验。

php高性能处理日志golang开辟类库篇一 Zap高机能日记类库的应用 NoSQL

怎么利用zap

我们说下大略的利用案例 首相当然是下载 go get -u go.uber.org/zap 先贴一个我这边常用的zap的配置

zap.Config{Level: zap.NewAtomicLevelAt(zap.DebugLevel),Development:true,Encoding:\"大众json\"大众,EncoderConfig: zapcore.EncoderConfig{TimeKey:\"大众t\"大众,LevelKey:\"大众level\公众,NameKey:\"大众log\"大众,CallerKey:\"大众caller\"大众,MessageKey:\公众msg\"大众,StacktraceKey:\公众trace\"大众,LineEnding: zapcore.DefaultLineEnding,EncodeLevel: zapcore.LowercaseLevelEncoder,EncodeTime:韶光格式函数,EncodeDuration: zapcore.SecondsDurationEncoder,EncodeCaller: zapcore.ShortCallerEncoder,},OutputPaths:[]string{\"大众/tmp/zap.log\"大众},ErrorOutputPaths:[]string{\"大众/tmp/zap.log\公众},InitialFields: map[string]interface{}{\"大众app\"大众:\"大众test\"大众,},}

基本配置的解释

Level:日志级别,跟其他措辞是一样的。
只不过它须要的类型是AtomicLevel。
以是须要利用zap.NewAtomicLevelAt做下如下的转化。

zap.NewAtomicLevelAt(zap.DebugLevel)zap.DebugLevelzap.InfoLevelzap.WarnLevelzap.ErrorLevel

Development:bool 是否是开拓环境。
如果是开拓模式,对DPanicLevel进行堆栈跟踪 DisableCaller:bool 禁止利用调用函数的文件名和行号来注释日志。
默认进行注释日志 DisableStacktrace:bool 是否禁用堆栈跟踪捕获。
默认对Warn级别以上和生产error级别以上的进行堆栈跟踪。
Encoding:编码类型,目前两种json 和 console【按照空格隔开】,常用json EncoderConfig:天生格式的一些配置--TODO 后面我们详细看下EncoderConfig配置各个解释 OutputPaths:[]string 日志写入文件的地址 ErrorOutputPaths:[]string 将系统内的error记录到文件的地址 InitialFields:map[string]interface{} 加入一些初始的字段数据,比如项目名 当然了,如果想掌握台输出,OutputPaths和ErrorOutputPaths不能配置为文件地址,而该当改为stdout。

关于config的配置,详细的可以参考文件里面的注释 go.uber.org/zap/config.go type Config struct

EncoderConfig配置解释

MessageKey:输入信息的key名 LevelKey:输出日志级别的key名 TimeKey:输出韶光的key名 NameKey CallerKey StacktraceKey跟以上类似,看名字就知道 LineEnding:每行的分隔符。
基本zapcore.DefaultLineEnding 即\"大众\n\公众 EncodeLevel:基本zapcore.LowercaseLevelEncoder。
将日志级别字符串转化为小写 EncodeTime:输出的韶光格式 EncodeDuration:一样平常zapcore.SecondsDurationEncoder,实行花费的韶光转化成浮点型的秒 EncodeCaller:一样平常zapcore.ShortCallerEncoder,以包/文件:行号 格式化调用堆栈 EncodeName:可选值。

详细EncoderConfig的解释,可以参考文件里面的注释 go.uber.org/zapcore/encoder.go type EncoderConfig struct

举个栗子

你扯这么多配置解释,谁有韶光看这玩意,写个常用的让大家照着用就好了嘛。

package mainimport(\公众fmt\"大众\"大众go.uber.org/zap\公众\公众go.uber.org/zap/zapcore\公众\"大众time\"大众)var logger zap.Loggerfunc formatEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder){ enc.AppendString(fmt.Sprintf(\"大众%d%02d%02d_%02d%02d%02d\"大众, t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()))}func FormateLog(args []interface{})zap.Logger{ log := logger.With(ToJsonData(args))return log}func Debug(msg string, args ...interface{}){FormateLog(args).Sugar().Debugf(msg)}func ToJsonData(args []interface{}) zap.Field{ det := make([]string,0)if len(args)>0{for _, v := range args { det = append(det, fmt.Sprintf(\公众%+v\公众, v))}} zap := zap.Any(\公众detail\公众, det)return zap}func InitZapLog(){ cfg := zap.Config{Level: zap.NewAtomicLevelAt(zap.DebugLevel),Development:true,Encoding:\"大众json\"大众,EncoderConfig: zapcore.EncoderConfig{TimeKey:\"大众t\"大众,LevelKey:\"大众level\公众,NameKey:\"大众logger\"大众,CallerKey:\公众caller\公众,MessageKey:\"大众msg\公众,StacktraceKey:\公众trace\"大众,LineEnding: zapcore.DefaultLineEnding,EncodeLevel: zapcore.LowercaseLevelEncoder,EncodeTime: formatEncodeTime,EncodeDuration: zapcore.SecondsDurationEncoder,EncodeCaller: zapcore.ShortCallerEncoder,},OutputPaths:[]string{\"大众/tmp/zap.log\公众},ErrorOutputPaths:[]string{\"大众/tmp/zap.log\"大众},InitialFields: map[string]interface{}{\公众app\"大众:\公众test\"大众,},}var err error logger, err = cfg.Build()if err !=nil{ panic(\"大众log init fail:\"大众+ err.Error())}}func main(){InitZapLog() defer logger.Sync() a :=[]string{\"大众test\"大众,\公众hello\公众,\公众world\"大众}Debug(\"大众output\"大众,a)}

实行下,就会在日志文件上输入按照我们配置日志格式。

tail -f /tmp/zap.log{\"大众level\"大众:\公众debug\"大众,\公众t\公众:\公众20190630_044053\公众,\"大众caller\"大众:\公众myproject/main.go:21\"大众,\"大众msg\"大众:\公众output\公众,\"大众app\公众:\"大众test\"大众,\"大众detail\公众:[\公众[test hello world]\"大众]}

然后我们试下掌握台输出,修正三个console干系的配置代码 ··· OutputPaths: []string{\公众stdout\"大众}, ErrorOutputPaths: []string{\"大众stdout\"大众}, 掌握台窗口就会输出 {\公众level\"大众:\公众debug\"大众,\"大众t\"大众:\"大众20190630_092533\"大众,\"大众caller\公众:\"大众myproject/main.go:21\"大众,\"大众msg\公众:\"大众output\"大众,\公众app\"大众:\公众test\"大众,\"大众detail\"大众:[\"大众[test hello world]\"大众]} ···

当然了,zap最想的利用和文档,看官网嘛 https://github.com/uber-go/zap https://godoc.org/go.uber.org/zap