gin:用zap实现异步日志

一,代码:

1,global/accessLogger.go

    初始化全局变量

package global

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
	"time"
)

var (
	LogFileAccess *os.File
	LoggerAccess *zap.Logger
)

//创建logger
func SetupAccessLogger() (error) {

	//现在得到一个iowriter
	filename := "/data/gologs/logs/access.log"
	LogFileAccess,_=os.OpenFile(filename,os.O_WRONLY|os.O_CREATE|os.O_APPEND,06666)

	//defer logFile.Close()
    //得到BufferedWriteSyncer
	asyncWriter := &zapcore.BufferedWriteSyncer{
		WS:            zapcore.AddSync(LogFileAccess),
		FlushInterval: time.Minute,    //1分钟后写入
		Size: 512 * 1024,              //超过512 kB后写入,
	}
    //得到encoderconfig
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "timestamp",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "message",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.CapitalLevelEncoder,  // INFO -> INFO
		EncodeTime:     zapcore.ISO8601TimeEncoder,   // 时间格式化
		EncodeDuration: zapcore.StringDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,   // caller 压缩显示
	}

    //得到encoder
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

	// 实现判断日志等级的interface
	infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.InfoLevel
	})

    //生成newCore
	//newCore:=zapcore.NewCore(encoder, asyncWriter, infoLevel)
	core := zapcore.NewTee(
		zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), infoLevel), //打印到控制台
		zapcore.NewCore(encoder, zapcore.AddSync(asyncWriter), infoLevel),   //打印到文件中
	)
    //生成logger实例
	LoggerAccess=zap.New(core)

    defer LoggerAccess.Sync()

	return nil
}

2, main中初始化

// 入口函数
func main() {

    //记录启动时间
    global.AppStartTime = time.Now()
    //日志初始化
    global.SetupAccessLogger()
    //数据库连接初始化
    global.SetupDBLink()

    defer global.LoggerAccess.Sync()
    defer global.LogFileAccess.Close()

    //引入路由
    r := routes.Routes()
    // r.Run(":8080")


    // 异步
    go func() {
        //run
        r.Run(":8080")
    }()

    // 如果想要接收到信号
    quit := make(chan os.Signal)
    // sigint 是有 CTRL+C 触发,进程可以捕获信号,并进行处理,
    // SIGTERM是有 kill 命令触发,进程可以捕获信号,并进行处理,
    // SIGKILL是有 kill -9 命令触发,进程无法捕获。
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    // 处理后续逻辑
    fmt.Println("开始关闭gin server...")
    global.LoggerAccess.Sync()
    global.LogFileAccess.Close()

}

3,实际调用中的代码:

		log:=envStr+"\n"+request+"\n"+final+"\nduration:"+fmt.Sprintf("%d",duration/1000)+"μs"
		global.LoggerAccess.Info(log, )

 

二,测试效果:

日志会在1分钟后或内容超过512k后写入到磁盘

posted @ 2025-02-23 17:36  刘宏缔的架构森林  阅读(186)  评论(0)    收藏  举报