复盘日志库zap框架
zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包。
main函数基本配置如下
core.Config = &core.ZapConf{
Level: "info", // 级别
Format: "console", // 输出 console json
Prefix: "[server]", // 前缀
Director: "logs", // 保存目录
LinkName: "latest_log", // 链接文件
ShowLine: true, // 是否显示行号
EncodeLevel: "LowercaseColorLevelEncoder", // 编码级
StacktraceKey: "stacktrace", // 栈名
LogInConsole: true, // 输出控制台
}
zapApp := core.InitZap(core.Config)
for i := 0; i < 10000000; i++ {
zapApp.Info("日志内容:", zap.Any("user", "001")) // 写入文件
}
defer zapApp.Sync()
核心配置如下
package core
import (
"fmt"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"os"
"path"
"time"
"zaptest/utils"
)
// ZapConf Zap配置结构
type ZapConf struct {
Level string `mapstructure:"level" json:"level" yaml:"level"` // 级别
Format string `mapstructure:"format" json:"format" yaml:"format"` // 输出
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 日志前缀
Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹
LinkName string `mapstructure:"link-name" json:"linkName" yaml:"link-name"` // 软链接名称
ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"` // 显示行
EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"` // 编码级
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"` // 栈名
LogInConsole bool `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console"` // 输出控制台
}
// Config 全局Zap配置
var Config *ZapConf
var Level zapcore.Level
func InitZap(config *ZapConf) (logger *zap.Logger) {
// 判断是否有存储日志文件夹
if ok, _ := utils.PathExists(config.Director); !ok {
// 不存在创建日志存储目录
fmt.Printf("create %v directory\n", config.Director)
_ = os.Mkdir(config.Director, os.ModePerm)
}
// 初始化配置文件的Level
switch config.Level {
case "debug":
Level = zap.DebugLevel
case "info":
Level = zap.InfoLevel
case "warn":
Level = zap.WarnLevel
case "error":
Level = zap.ErrorLevel
case "dpanic":
Level = zap.DPanicLevel
case "panic":
Level = zap.PanicLevel
case "fatal":
Level = zap.FatalLevel
default:
Level = zap.InfoLevel
}
if Level == zap.DebugLevel || Level == zap.ErrorLevel {
logger = zap.New(getEncoderCore(), zap.AddStacktrace(Level))
} else {
logger = zap.New(getEncoderCore())
}
// 如果开启行号
if config.ShowLine {
logger = logger.WithOptions(zap.AddCaller())
}
return logger
}
// CustomTimeEncoder 自定义日志输出时间格式
func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format(Config.Prefix + "2006/01/02 - 15:04:05.000"))
}
// getEncoderConfig 获取zapcore.EncoderConfig
func getEncoderConfig() (conf zapcore.EncoderConfig) {
conf = zapcore.EncoderConfig{
MessageKey: "message",
LevelKey: "level",
TimeKey: "time",
NameKey: "logger",
CallerKey: "caller",
StacktraceKey: Config.StacktraceKey,
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: CustomTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.FullCallerEncoder,
}
switch {
case Config.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
conf.EncodeLevel = zapcore.LowercaseLevelEncoder
case Config.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
conf.EncodeLevel = zapcore.LowercaseColorLevelEncoder
case Config.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
conf.EncodeLevel = zapcore.CapitalLevelEncoder
case Config.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
conf.EncodeLevel = zapcore.CapitalColorLevelEncoder
default:
conf.EncodeLevel = zapcore.LowercaseLevelEncoder
}
return conf
}
// 获取核心
func getEncoderCore() (core zapcore.Core) {
// 按照日期写入文件
//writer, err := GetWriteSyncerByDate()
//if err != nil {
// fmt.Printf("Get Write Syncer Failed err:%v", err.Error())
// return
//}
// 按照大小写入文件
writer := GetWriteSyncerBySize()
return zapcore.NewCore(getEncoder(), writer, Level)
}
// 判断是json还是console格式化
func getEncoder() zapcore.Encoder {
if Config.Format == "json" {
return zapcore.NewJSONEncoder(getEncoderConfig())
}
return zapcore.NewConsoleEncoder(getEncoderConfig())
}
// GetWriteSyncerByDate 按照日期分割日志
func GetWriteSyncerByDate() (zapcore.WriteSyncer, error) {
fileWriter, err := rotatelogs.New(
//path.Join(Config.Director, "%Y-%m-%d.log"), // 日志文件名
//rotatelogs.WithMaxAge(7*24*time.Hour), // 日志最大保存时间
//rotatelogs.WithRotationTime(24*time.Minute), // 日志轮转时间
//rotatelogs.WithLinkName(Config.LinkName),
//每分钟
path.Join(Config.Director, "%Y-%m-%d-%H-%M.log"),
rotatelogs.WithLinkName(Config.LinkName), //生成软链,指向最新日志文件
rotatelogs.WithRotationTime(time.Minute), //最小为1分钟轮询。默认60s 低于1分钟就按1分钟来
rotatelogs.WithRotationCount(3), //设置3份 大于3份 或到了清理时间 开始清理
rotatelogs.WithRotationSize(1*1024*1024), //设置100MB大小,当大于这个容量时,创建新的日志文件
//rotatelogs.WithRotationSize(100),
//rotatelogs.WithRotationTime(24*time.Hour), // 日志轮转时间
)
if err != nil {
return nil, err
}
if Config.LogInConsole {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)), nil
}
return zapcore.AddSync(fileWriter), nil
}
// GetWriteSyncerBySize 按照大小分割日志
func GetWriteSyncerBySize() zapcore.WriteSyncer {
fileWriter := &lumberjack.Logger{
Filename: Config.Director + "/app.log", // 日志文件名
MaxSize: 1, // 每个日志文件的最大尺寸(单位:MB)
MaxBackups: 5, // 保留的旧日志文件的最大数量
MaxAge: 7, // 保留的日志文件最大天数
Compress: true, // 是否压缩日志文件
}
if Config.LogInConsole {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter))
}
return zapcore.AddSync(fileWriter)
}
// GetWriteSyncerByDateAndSize 日期日志 + 大小日志
func GetWriteSyncerByDateAndSize() (zapcore.WriteSyncer, error) {
// 按日期分割
dateWriter, err := rotatelogs.New(
path.Join(Config.Director, "%Y-%m-%d.log"),
rotatelogs.WithMaxAge(7*24*time.Hour),
rotatelogs.WithRotationTime(24*time.Hour),
)
if err != nil {
return nil, err
}
// 按大小分割
sizeWriter := &lumberjack.Logger{
Filename: Config.Director + "/app.log",
MaxSize: 1, // 1MB
MaxBackups: 5,
MaxAge: 7,
Compress: true,
}
// 同时输出到日期和大小分割的日志
if Config.LogInConsole {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(dateWriter), zapcore.AddSync(sizeWriter)), nil
}
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(dateWriter), zapcore.AddSync(sizeWriter)), nil
}
// PathExists 检查路径是否存在
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
共有 0 条评论