gopackage logger
import (
"fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"im-services/internal/config"
"os"
"strings"
"time"
)
// 参考 https://learnku.com/courses/go-api/1.17/using-zap/11782
// Logger 全局 Logger 对象
var Logger *zap.Logger
// InitLogger 日志初始化
func InitLogger(filename string, maxSize, maxBackup, maxAge int, compress bool, logType string, level string) {
// 获取日志写入介质
writeSyncer := getLogWriter(filename, maxSize, maxBackup, maxAge, compress, logType)
// 设置日志等级,具体请见 config/log.go 文件
logLevel := new(zapcore.Level)
if err := logLevel.UnmarshalText([]byte(level)); err != nil {
fmt.Println("日志初始化错误,日志级别设置有误. 请调整配置")
}
// 初始化 core
core := zapcore.NewCore(getEncoder(), writeSyncer, logLevel)
// 初始化 Logger
Logger = zap.New(core,
zap.AddCaller(), // 调用文件和行号,内部使用 runtime.Caller
zap.AddCallerSkip(1), // 封装了一层,调用文件去除一层(runtime.Caller(1))
zap.AddStacktrace(zap.ErrorLevel), // Error 时才会显示 stacktrace
)
// 将自定义的 logger 替换为全局的 logger
// zap.L().Fatal() 调用时,就会使用我们自定的 Logger
zap.ReplaceGlobals(Logger)
}
// getEncoder 设置日志存储格式
func getEncoder() zapcore.Encoder {
// 日志格式规则
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller", // 代码调用,如 paginator/paginator.go:148
FunctionKey: zapcore.OmitKey,
MessageKey: "message",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding, // 每行日志的结尾添加 "\n"
EncodeLevel: zapcore.CapitalLevelEncoder, // 日志级别名称大写,如 ERROR、INFO
EncodeTime: customTimeEncoder, // 时间格式,我们自定义为 2006-01-02 15:04:05
EncodeDuration: zapcore.SecondsDurationEncoder, // 执行时间,以秒为单位
EncodeCaller: zapcore.ShortCallerEncoder, // Caller 短格式,如:types/converter.go:17,长格式为绝对路径
}
// 本地环境配置
if config.IsLocal() {
// 终端输出的关键词高亮
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
// 本地设置内置的 Console 解码器(支持 stacktrace 换行)
return zapcore.NewConsoleEncoder(encoderConfig)
}
// 线上环境使用 JSON 编码器
return zapcore.NewJSONEncoder(encoderConfig)
}
// customTimeEncoder 自定义友好的时间格式
func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05"))
}
// getLogWriter 日志记录介质。Github 中使用了两种介质,os.Stdout 和文件
func getLogWriter(filename string, maxSize, maxBackup, maxAge int, compress bool, logType string) zapcore.WriteSyncer {
// 如果配置了按照日期记录日志文件
if logType == "daily" {
logName := time.Now().Format("2006-01-02.log")
filename = strings.ReplaceAll(filename, "logs.log", logName)
}
// 滚动日志,详见 config/log.go
lumberJackLogger := &lumberjack.Logger{
Filename: filename,
MaxSize: maxSize,
MaxBackups: maxBackup,
MaxAge: maxAge,
Compress: compress,
}
// 配置输出介质
if config.IsLocal() {
// 本地开发终端打印和记录文件
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger))
} else {
// 生产环境只记录文件
return zapcore.AddSync(lumberJackLogger)
}
}
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!