golang的zap日志库的简单封装

mediaufo · · 1121 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

项目的需要,对zap日志库做了简单的封装,主要是支持如下的功能: `1、支持同步和异步的方式。` `2、支持根据不同的日志级别调用不同的writer处理.` 具体实现如下 ``` type ZapLogOper interface { Debug(msg string, fields ...zap.Field) Info(msg string, fields ...zap.Field) Warn(msg string, fields ...zap.Field) Error(msg string, fields ...zap.Field) DPanic(msg string, fields ...zap.Field) Panic(msg string, fields ...zap.Field) Fatal(msg string, fields ...zap.Field) } //同步日志,直接写 type synczaplogger struct { zaplog *zap.Logger } //异步日志 type asynczaplogger struct { zaplog *zap.Logger masyslog *asynclogger } type zaplogger struct { zaplog *zap.Logger masyslog *asynclogger } func setzaplogger(nwriters map[zapcore.Level]zapcore.WriteSyncer) *zap.Logger { encoderConfig := zapcore.EncoderConfig{ TimeKey: "time", MessageKey: "msg", LevelKey: "level", NameKey: "logger", CallerKey: "caller", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, //EncodeName: zapcore.FullNameEncoder, } encoder := zapcore.NewJSONEncoder(encoderConfig) lvlenabler := zap.NewAtomicLevel() fcore := newfilecore(encoder, nwriters, lvlenabler) zaplog := zap.New(fcore) return zaplog } func newsynczaplogger(nwriters map[zapcore.Level]zapcore.WriteSyncer) *synczaplogger { retlogger := &synczaplogger{} retlogger.zaplog = setzaplogger(nwriters) return retlogger } func newasynczaplogger(nwriters map[zapcore.Level]zapcore.WriteSyncer) *asynczaplogger { retlogger := &asynczaplogger{} retlogger.zaplog = setzaplogger(nwriters) //设置异步的操作 retlogger.masyslog = newAsyncLogger() return retlogger } //返回接口 func NewZapLogger(wtMode int, nwriters map[zapcore.Level]zapcore.WriteSyncer) ZapLogOper { if wtMode == 0 { return newsynczaplogger(nwriters) } else { return newasynczaplogger(nwriters) } } func NewAllZapLogger(nwriters map[zapcore.Level]zapcore.WriteSyncer) ZapLogOper { retzaplogger := &zaplogger{} retzaplogger.zaplog = setzaplogger(nwriters) retzaplogger.masyslog = newAsyncLogger() return retzaplogger } func (log *zaplogger) Debug(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Debug, msg, fields...) } func (log *zaplogger) Info(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Info, msg, fields...) } func (log *zaplogger) Warn(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Warn, msg, fields...) } func (log *zaplogger) Error(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Error, msg, fields...) } func (log *zaplogger) DPanic(msg string, fields ...zap.Field) { log.zaplog.DPanic(msg, fields...) } func (log *zaplogger) Panic(msg string, fields ...zap.Field) { log.zaplog.Panic(msg, fields...) } func (log *zaplogger) Fatal(msg string, fields ...zap.Field) { log.zaplog.Fatal(msg, fields...) } //------- func (log *synczaplogger) Debug(msg string, fields ...zap.Field) { log.zaplog.Debug(msg, fields...) } func (log *synczaplogger) Info(msg string, fields ...zap.Field) { log.zaplog.Info(msg, fields...) } func (log *synczaplogger) Warn(msg string, fields ...zap.Field) { log.zaplog.Warn(msg, fields...) } func (log *synczaplogger) Error(msg string, fields ...zap.Field) { log.zaplog.Error(msg, fields...) } func (log *synczaplogger) DPanic(msg string, fields ...zap.Field) { log.zaplog.DPanic(msg, fields...) } func (log *synczaplogger) Panic(msg string, fields ...zap.Field) { log.zaplog.Panic(msg, fields...) } func (log *synczaplogger) Fatal(msg string, fields ...zap.Field) { log.zaplog.Fatal(msg, fields...) } func (log *asynczaplogger) Debug(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Debug, msg, fields...) } func (log *asynczaplogger) Info(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Info, msg, fields...) } func (log *asynczaplogger) Warn(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Warn, msg, fields...) } func (log *asynczaplogger) Error(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Error, msg, fields...) } func (log *asynczaplogger) DPanic(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.DPanic, msg, fields...) } func (log *asynczaplogger) Panic(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Panic, msg, fields...) } func (log *asynczaplogger) Fatal(msg string, fields ...zap.Field) { log.masyslog.doAsyncLog(log.zaplog.Fatal, msg, fields...) } 异步的简单实现: const ( cst_defmsgsize = 200 cst_deffieldnums = 2 cst_defmaxlogquenums = 500 ) var _asyncMsgPool = sync.Pool{ New: func() interface{} { return &asyncMsg{msg: make([]byte, 0, cst_defmsgsize), fields: make([]zap.Field, 0, cst_deffieldnums)} }, } func newAsyncLogger() *asynclogger { mret := &asynclogger{logMsgCh: make(chan *asyncMsg, cst_defmaxlogquenums)} mret.start() return mret } func getAsyncMsg() *asyncMsg { return _asyncMsgPool.Get().(*asyncMsg) } func putAsynMsg(e *asyncMsg) { e.msg = e.msg[:0] e.fields = e.fields[:0] e.f = nil _asyncMsgPool.Put(e) } type asyncMsg struct { msg []byte fields []zap.Field f func(msg string, fields ...zap.Field) } //异步日志 type asynclogger struct { //异步队列数据 logMsgCh chan *asyncMsg } func (log *asynclogger) start() { go log.doWriteLog() } func (log *asynclogger) doWriteLog() { for logdata := range log.logMsgCh { //可以分池来处理 logdata.f(string(logdata.msg), logdata.fields...) putAsynMsg(logdata) } } func (log *asynclogger) doAsyncLog(f func(msg string, fields ...zap.Field), msg string, fields ...zap.Field) { logdata := getAsyncMsg() logdata.msg = append(logdata.msg, msg...) logdata.fields = append(logdata.fields, fields...) logdata.f = f log.logMsgCh <- logdata } zap.Core接口的实现 type filecore struct { zapcore.LevelEnabler enc zapcore.Encoder writers map[zapcore.Level]zapcore.WriteSyncer } type FileCore interface { zapcore.Core } func newfilecore(enc zapcore.Encoder, nwriters map[zapcore.Level]zapcore.WriteSyncer, enab zapcore.LevelEnabler) FileCore { retcore := &filecore{ LevelEnabler: enab, enc: enc, } retcore.writers = make(map[zapcore.Level]zapcore.WriteSyncer) for k, v := range nwriters { retcore.writers[k] = v } return retcore } func (c *filecore) With(fields []zapcore.Field) zapcore.Core { clone := c.clone() for i := range fields { fields[i].AddTo(clone.enc) } return clone } func (c *filecore) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { if c.Enabled(ent.Level) { return ce.AddCore(ent, c) } return ce } func (c *filecore) Write(ent zapcore.Entry, fields []zapcore.Field) error { buf, err := c.enc.EncodeEntry(ent, fields) if err != nil { return err } if _,ok:=c.writers[ent.Level];!ok { return errors.New("no set level writers") } _, err = c.writers[ent.Level].Write(buf.Bytes()) buf.Free() if err != nil { return err } if ent.Level > zapcore.ErrorLevel { c.writers[ent.Level].Sync() } return nil } func (c *filecore) Sync() error { return nil } func (c *filecore) clone() *filecore { retclone := &filecore{ LevelEnabler: c.LevelEnabler, enc: c.enc.Clone(), } retclone.writers = make(map[zapcore.Level]zapcore.WriteSyncer) for k, v := range c.writers { retclone.writers[k] = v } return retclone } ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1121 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传