跳转至

Go日志管理 zap

概要: 使用zap包处理go的日志问题

创建时间: 2023.09.26 23:37:17

更新时间: 2023.09.26 23:56:27

需求

  • 简单易用,高性能日志
  • 支持自定义日期格式、日志等级、行信息
  • 支持写入到文件,支持文件体积达到设定的阈值后自动分割,支持文件最大保留个数

zap包

Blazing fast, structured, leveled logging in Go.

zap是由Uber开源的高性能、结构化的分级日志框架。
主要特点如下

  1. 高性能: zap 使用零分配的 JSON 编码器,避免了使用 interface{} 和反射导致的性能开销
  2. 结构化: zap 支持结构化日志,可以将日志信息以 JSON 格式记录
  3. 多级别: zap 支持七种日志级别,分别是 DebugInfoWarnErrorDPanicPanicFatal
  4. 格式化: zap 支持自定义日志格式,可以通过设置日志格式模板来控制日志输出的内容
  5. 输出方式多样: zap 支持多种日志输出方式,包括文件、标准输出、HTTP 和 TCP

准备

Bash
1
2
3
go get -v gopkg.in/natefinch/lumberjack.v2
go get -v go.uber.org/zap
go get -v go.uber.org/zap/zapcore

代码

Go
package main

import (
    "fmt"
    "gopkg.in/natefinch/lumberjack.v2"
    "os"
    "time"

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

// 自定义的时间编码函数
func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
    enc.AppendString(t.Format("2006/01/02 15:04:05.000"))
}

// 自定义的日志等级编码函数
func customLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
    enc.AppendString(fmt.Sprintf("[%s]", level.CapitalString()))
}

// 自定义的日志行信息编码函数
func customCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
    enc.AppendString(fmt.Sprintf("%s", caller.TrimmedPath()))
}

// 获取 log 实例
func getLogger(logFilePath string) *zap.Logger {
    var coreArr []zapcore.Core
    // setup encoder
    encoderConfig := zap.NewProductionEncoderConfig()
    encoderConfig.EncodeTime = customTimeEncoder
    encoderConfig.EncodeLevel = customLevelEncoder
    encoderConfig.EncodeCaller = customCallerEncoder
    encoder := zapcore.NewConsoleEncoder(encoderConfig)

    // setup writer
    writeSyncer := zapcore.AddSync(&lumberjack.Logger{
        Filename:   logFilePath, // 日志文件存放路径,如果不存在会自动创建
        MaxSize:    50,          // 文件大小限制,单位MB
        MaxBackups: 100,         // 最大保留日志文件数量
        MaxAge:     30,          // 日志文件保留天数
        Compress:   false,       // 是否压缩处理
    })
    // to show log on console, uncomment next line
    writeSyncer = zapcore.NewMultiWriteSyncer(writeSyncer, zapcore.AddSync(os.Stdout))

    // setup log
    fileCore := zapcore.NewCore(encoder, writeSyncer, zap.DebugLevel)
    coreArr = append(coreArr, fileCore)
    return zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) // zap.AddCaller()为显示文件名和行号
}

func main() {
    log := getLogger("./demo.log")
    log.Debug("hello, debug")
    log.Info("hello, info")
    log.Warn("hello, warn")
    log.Error("hello, error")
}

输出到终端
image.png
输出到文件
image.png

参考