# Day15 Gin框架之zap日志库
# 日志记录器介绍
一个好的日志记录器应具备这些功能:
- 能够将事件记录到文件中,而不仅仅是应用程序控制台;
- 日志切割,如根据大小、时间或时间间隔等切割日志文件;
- 支持不同的日志级别,如INFO,DEBUG,ERROR等;
- 能够打印基本信息,如调用文件/函数名和行号,日志时间等;
# 内置日志库 Logger
- 仅支持配置日志输出
io.Writer
,无日志分级、切割、格式化等能力
package main
import (
"log"
"os"
)
func SetupLogger() {
logFileLocation, _ := os.OpenFile("./default.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
log.SetOutput(logFileLocation)
}
func main() {
SetupLogger()
log.Println("Fetch url err:", "www.baidu.com")
}
# 开源日志库 Zap
uber-go 开源,基本支持日志记录器介绍
- 安装依赖
go get -u go.uber.org/zap
- 基本使用
package main
import "go.uber.org/zap"
func main() {
// logger := zap.NewExample()
// logger, err := zap.NewDevelopment()
logger, err := zap.NewProduction() // 用这个就行,输出json更完善
if err != nil {
panic(err)
}
var uid int64 = 10000111
married := false
name := "linda"
data := []int{1001, 1002, 1003}
// 固定类型-性能输出; 固定json格式, 兼容EFK等
logger.Info("日志信息",
zap.Int64("uid", uid),
zap.Bool("married", married),
zap.String("name", name),
zap.Ints("data", data),
)
}
/*
1. 性能强悍
2. 格式化输出
*/
- 格式说明
func (log *Logger) Info(msg string, fields ...zapcore.Field)
1. 日志级别 Debug、Info、Warn、Error、DPanic、Panic、Fatal
2. msg 定义具体的业务场景
3. zapcore.Field 一组键值对参数,如 zap.Int64("uid", uid)
- 结果输出
{"level":"info","ts":1670493677.338023,"caller":"day15/main.go:19","msg":"日志信息","uid":10000111,"married":false,"name":"linda","data":[1001,1002,1003]}
{"level":"info","ts":1670493678.961177,"caller":"day15/main.go:19","msg":"日志信息","uid":10000111,"married":false,"name":"linda","data":[1001,1002,1003]}
# 定制日志库 Zap
- 基本定制 三步走
package main
import (
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
// 1. Encoder 编码器(以怎样格式写入日志),如 json 格式
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
// encoder := zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()) // 文本格式
// 2. WriterSyncer 指定日志将写到哪里去,如 写到文件
logFileLocation, _ := os.OpenFile("./zap.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
writeSyncer := zapcore.AddSync(logFileLocation)
// 3. Log Level 哪种级别的日志将被写入
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
// 最终汇总为core
logger := zap.New(core)
var uid int64 = 10000111
logger.Debug("日志级别", zap.Int64("uid", uid))
logger.Info("日志级别", zap.Int64("uid", uid))
}
/*
{"level":"debug","ts":1670494920.1061609,"msg":"日志级别","uid":10000111}
{"level":"info","ts":1670494920.106252,"msg":"日志级别","uid":10000111}
*/
# 精细化配置 Zap
package main
import (
"io"
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
// 1. Encoder
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 时间格式 2022-12-08T18:24:07.979+0800
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder // 大写 "level":"INFO"
encoderConfig.TimeKey = "timestamp" // "timestamp":"2022-12-08T18:41:35.596+0800"
encoder := zapcore.NewJSONEncoder(encoderConfig)
// 2. WriterSyncer 同时输出到文件和控制台
logFileLocation, _ := os.OpenFile("./zap.app.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
writeSyncer := zapcore.AddSync(io.MultiWriter(logFileLocation, os.Stdout))
// 汇总配置1
core1 := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
// 汇总配置2 将err日志单独输出到文件
errFileLocation, _ := os.OpenFile("./zap.err.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
core2 := zapcore.NewCore(encoder, zapcore.AddSync(errFileLocation), zap.ErrorLevel)
// 统一汇总
core := zapcore.NewTee(core1, core2)
// 调用函数信息 如 "caller":"day15/main.go:27", zap.AddCallerSkip(1)用于额外封装一层场景
logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
var uid int64 = 10000111
logger.Debug("日志级别", zap.Int64("uid", uid))
logger.Info("日志级别", zap.Int64("uid", uid))
logger.Error("日志级别", zap.Int64("uid", uid))
}
- 定制输出格式,如时间Key名称和格式等
- Error日志输出到单独文件,便于排错;
- Debug级别日志可以同时输出到指定文件和控制台
# 日志切割 Lumberjack
Zap本身不支持切割归档日志文件
安装依赖
go get gopkg.in/natefinch/lumberjack.v2
- 基本使用
package main
import (
"io"
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
// 输出到 lumberJackLogger
lumberJackLogger := &lumberjack.Logger{
Filename: "./zap.app.log", // 日志文件的位置
MaxSize: 1, // 在进行切割之前,日志文件的最大大小(以MB为单位)
MaxBackups: 5, // 保留旧文件的最大个数
MaxAge: 30, // 保留旧文件的最大天数
Compress: false, // 是否压缩/归档旧文件
}
writeSyncer := zapcore.AddSync(io.MultiWriter(lumberJackLogger, os.Stdout))
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
logger := zap.New(core, zap.AddCaller())
var uid int64 = 10000111
for {
logger.Debug("日志级别", zap.Int64("uid", uid))
}
}
- 实测结果 只保留5个