两个高性能golang日志库比较_第1页
两个高性能golang日志库比较_第2页
两个高性能golang日志库比较_第3页
两个高性能golang日志库比较_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

两个⾼性能golang⽇志库⽐较nanologvszerolog后端开发过程中,经常需要对⼀些重要的事件做⽇志,⽅便观察程序的控制流,建⽴对程序的理解和⾃信,对于缺少好⽤debugger()的golang来说,⽇志更是重要的调试⼿段。⼤部分时候,使⽤标准库⾃带的logpackage已经够⽤,log包缺少输出级别的控制,不过我们可以基于log包做简单的包装也⾜以够⽤,尽量减少对第三⽅包的依赖,我觉得应该是个好实践。不过当你发现log太多,对程序性能产⽣了明显的影响时,也许可以考虑下⾯介绍的两个⽇志库:和。nanolog是受到同名c++库nanolog启发,zerolog是受到uber的⽇志库zap的启发,。⾸先,看⼀下nanolog是怎么个使⽤法:packagemainimport("os""/ScottMansfield/nanolog")varhnanolog.Handlefuncinit(){nanolog.SetWriter(os.Stderr)h=nanolog.AddLogger("Example%i32log%{s}line%c128")}funcmain(){nanolog.Log(h,int32(4),"thisisastring",4i)nanolog.Flush()}nanolog的思路是每个独特的printf风格的字符串模板,映射⼀个唯⼀的整数handle。当我们调⽤AddLogger⽅法时,触发解析string模板,收集了三个string⽚段:“Example","log","line";三个占位符的类别:i32,s,c128;然后往内存buffer⾥先写⼀字节的ETLogLine(1),然后就是暴露给⽤户的handleh,字符串⽚段个数,⼀字节编码的多个类别,字符串⽚段本⾝。调⽤Log⽅法时,开始写占位符对应的实际参数:⾸先写ETLogEntry(2),接着是handle,然后是⼤⼩1,2,4,8,16字节的各种基础数据类型对应的值。需要注意的是,上⾯⽇志数据都是往bufferwriter⾥⾯发送,所以后⾯需要调⽤Flush()。不过,由于作者使⽤了⾃定义的格式编码⽇志,减少⽇志的磁盘空间占⽤,所以阅读⽇志不太⽅便,需要⾃带的inflate⼯具还原:$gobuild/ScottMansfield/nanolog/cmd/inflate$./inflate-ffoo.clog>foo-inflated.logzerolog基本上是logrus,zap这条路线上的,输出带上下⽂信息的json,但是在性能追求上更进⼀步。这种结构化⽇志库,⼈类易读性差点,但是⽅便⽇志搜集程序的处理。api设计成这种可chaining模式,⽐zap使⽤上感觉要优雅多了,和zap⼀样,输出json时,⼿⼯定义的json序列化⽅法避免,使⽤相对昂贵的标准库encoding/json,zerolog还引⼊了和context库结合,⽅便将logger存⼊context。起初感到奇怪的是它的api有不少地⽅⽅法接收器都是⽤T,⽽⾮*T,后来⼀想,这正在完成channing模式,减少内存分配,childrenlogger不会⼲扰parentlogger的⽀撑。funcNew(wio.Writer)Logger{ifw==nil{w=ioutil.Discard}lw,ok:=w.(LevelWriter)if!ok{lw=levelWriterAdapter{w}}returnLogger{w:lw}}//Nopreturnsadisabledloggerforwhichalloperationareno-op.funcNop()Logger{returnNew(nil).Level(Disabled)}//Withcreatesachildloggerwiththefieldaddedtoitscontext.func(lLogger)With()Context{context:=l.contextl.context=make([]byte,0,500)ifcontext!=nil{l.context=append(l.context,context...)}else{//firstbyteofcontextispresenceoftimestampornotl.context=append(l.context,0)}returnContext{l}}//Levelcreatesachildloggerwiththeminimumacceptedlevelsettolevel.func(lLogger)Level(lvlLevel)Logger{returnLogger{w:l.w,level:lvl,sample:l.sample,counter:l.counter,context:l.context,}}//Samplereturnsaloggerthatonlyletonemessageoutofeverytopassthru.func(lLogger)Sample(everyint)Logger{ifevery==0{//Createachildwithnosampling.returnLogger{w:l.w,level:l.level,context:l.context,}}returnLogger{w:l.w,level:l.level,sample:uint32(every),counter:new(uint32),context:l.context,}}这⼏个构造器函数都是返回结构体实例,复制原有对象必要的字段,这样parent,childlogger,带有不同上下⽂的logger之间互不⼲扰。简单的benchmark⼀下,nanolog,zerolog,stdlog:packagemainimport("io/ioutil""log""testing""/ScottMansfield/nanolog""/rs/zerolog")funcBenchmarkCompareToStdlib(b*testing.B){b.Run("Nanolog",func(b*testing.B){lw:=nanolog.New()lw.SetWriter(ioutil.Discard)h:=lw.AddLogger("foothingbarthing%i64.Fubar%sfoo.sadfasdf%u32sdfasfasdfasdffds%u32.")args:=[]interface{}{int64(1),"string",uint32(2),uint32(3)}b.ResetTimer()fori:=0;i<b.N;i++{lw.Log(h,args...)}})b.Run("Stdlib",func(b*testing.B){args:=[]interface{}{int64(1),"string",uint32(2),uint32(3)}l:=log.New(ioutil.Discard,"",0)b.ResetTimer()fori:=0;i<b.N;i++{l.Printf("foothingbarthing%d.Fubar%sfoo.sadfasdf%dsdfasfasdfasdffds%d.",args...)}})b.Run("Zerolog_printf",func(b*testing.B){args:=[]interface{}{int64(1),"string",uint32(2),uint32(3)}logger:=zerolog.New(ioutil.Discard)b.ResetTimer()fori:=0;i<b.N;i++{logger.Log().Msgf("foothingbarthing%d.Fubar%sfoo.sadfasdf%dsdfasfasdfasdffds%d.",args...)}})b.Run("Zerolog_field",func(b*testing.B){logger:=zerolog.New(ioutil.Discard)b.ResetTimer()fori:=0;i<b.N;i++{logger.Log().Int64("foothingbarthing",1).Str("Fubarfoo","string").Uint32("sadfasdf",2).Uint32("sdfasfasdfasdffds",3).Msg("")}})b.Run("Zerolog_context",func(b*testing.B){logger:=zerolog.New(ioutil.Discard).With().Int64("foothingbarthing",1).Str("Fubarfoo","string").Uint32("sadfasdf",2).Uint32("sdfasfasdfasdffds",3).Logger()b.ResetTimer()fori:=0;i<b.N;i++{logger.Log().Msg("")}})}$gotest-benchStdlib$.BenchmarkCompareToStdlib/Nanolog-8BenchmarkCompareToStdlib/Stdlib-820000000500000090.2ns/op364ns/opBenchmarkCompareToStdlib/Z

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论