目 录CONTENT

文章目录
Go

zap 日志库自定义 WriteSyncer

Hello!你好!我是村望~!
2023-04-18 / 0 评论 / 0 点赞 / 207 阅读 / 774 字
温馨提示:
我不想探寻任何东西的意义,我只享受当下思考的快乐~

zap 日志库自定义 WriteSyncer

顺便问一下,将日志同步实时写入到数据库库真的好吗?

不过群友备注的很谨慎哈哈哈!

image-20230418102529464

今日水群!看到一群友,提出一个这样的小问题!

突然自己也想试试!

首先复习一下如何初始化一个 zap 日志库的!

首先通过 zap.New 方法 !

zap.New 接收一个 zapcore.Core 类型的参数!

zapcore.Core 使用zapcore.NewCore() 生成!

func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core

需要三个配置::分别指定日志的一些输出规则!

  • Encoder 编码器(如何写入日志)
  • WriteSyncer 指定日志将写到哪里去
  • LogLevel 哪种级别的日志将被写入

那么 WriteSyncer 控制着日志内容输出的位置!我们就来试着自己实现一个自定义的 WriteSyncer

(自己之前都是直接传文件io.Writer或者Stdout输出控制台的没有想过自定义!)

这次我来看看如何实现自己的 WriteSyncer首先看看 这个接口定义

(简单的有点过分了,这个文章不写也罢!)

type WriteSyncer interface {
	io.Writer
	Sync() error
}

然后我们就去自己实现一下这个接口!

type MyWriteSyncer struct {
	file *os.File
}

func NewFileWriteSyncer(filename string) (*MyWriteSyncer, error) {
	file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}
	return &MyWriteSyncer{file: file}, nil
}

func (f *MyWriteSyncer) Write(p []byte) (int, error) {
	// 做爱做的事
	var data map[string]interface{}
	if err := json.Unmarshal(p, &data); err != nil {
		panic(err)
	}
	fmt.Println(data["msg"]) // 输出: map[
	return f.file.Write(p)
}

func (f *MyWriteSyncer) Sync() error {
	return f.file.Sync()
}

func (f *MyWriteSyncer) Close() error {
	return f.file.Close()
}

本身内部有个 io.Writer zap 肯定也是通过这个 io.Writer 去做输出的!

就可以从它的 Write(p []byte) 拿到输出到内容,也就是我们的日志内容!做一些序列化就可以了!

拿到日志,你就可以把它写入到数据库或者干点其他都行!

来做个测试试一下!

func TestCustomLoggerTest(t *testing.T) {
	logger, _ := InitLogger()
	logger.Info("鸭哥 重金求富婆")
}

image-20230418104016346

完美!

完整代码:

package logs

import (
	"encoding/json"
	"fmt"
	"os"
	"testing"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type MyWriteSyncer struct {
	file *os.File
}

func NewFileWriteSyncer(filename string) (*MyWriteSyncer, error) {
	file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}
	return &MyWriteSyncer{file: file}, nil
}

func (f *MyWriteSyncer) Write(p []byte) (int, error) {
	// 做爱做的事
	var data map[string]interface{}
	if err := json.Unmarshal(p, &data); err != nil {
		panic(err)
	}
	fmt.Println(data["msg"]) // 输出: map
	return f.file.Write(p)
}

func (f *MyWriteSyncer) Sync() error {
	return f.file.Sync()
}

func (f *MyWriteSyncer) Close() error {
	return f.file.Close()
}

// log 输出编码配置!
func setEncoder() zapcore.Encoder {
	encodeConfig := zap.NewProductionEncoderConfig()
	encodeConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encodeConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return zapcore.NewJSONEncoder(encodeConfig)
}

func customWriterSync() zapcore.WriteSyncer {
	syncer, _ := NewFileWriteSyncer("customWriterSync_logs")
	return syncer
}
func InitLogger() (logger *zap.Logger, err error) {
	if err != nil {
		return nil, err
	}
	core := zapcore.NewCore(setEncoder(), customWriterSync(), zapcore.DebugLevel)
	logger = zap.New(core, zap.AddCaller())
	return logger, nil
}

func TestCustomLoggerTest(t *testing.T) {
	logger, _ := InitLogger()
	logger.Info("鸭哥 重金求富婆")
}

总结:简单 实现接口就行!

0

评论区