Files
workspace/code/allapp/allapp-go-v3/pkg/logger/logger.go
T
2026-04-02 22:07:21 +08:00

171 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logger
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/gofiber/fiber/v3"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var Log *zap.Logger
const TraceIDKey = "request_id"
// ======================
// 配置结构
// ======================
type Config struct {
Dir string // 日志目录
Level string // debug info warn error
MaxSize int // MB
MaxBackups int
MaxAge int // 天
Compress bool // 是否压缩
}
// ======================
// 初始化
// ======================
func Init(cfg Config) {
if cfg.Dir == "" {
cfg.Dir = "logs"
}
if cfg.Level == "" {
cfg.Level = "info"
}
level := parseLevel(cfg.Level)
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
MessageKey: "msg",
CallerKey: "caller",
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
encoder := zapcore.NewJSONEncoder(encoderConfig)
// 控制台
consoleWriter := zapcore.AddSync(os.Stdout)
// 文件 writer(info)
infoWriter := getWriter(cfg, "info")
// 文件 writer(error)
errorWriter := getWriter(cfg, "error")
// info core
infoCore := zapcore.NewCore(
encoder,
zapcore.NewMultiWriteSyncer(consoleWriter, infoWriter),
zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.ErrorLevel && lvl >= level
}),
)
// error core
errorCore := zapcore.NewCore(
encoder,
zapcore.NewMultiWriteSyncer(consoleWriter, errorWriter),
zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.ErrorLevel
}),
)
core := zapcore.NewTee(infoCore, errorCore)
Log = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
}
// ======================
// lumberjack writer
// ======================
func getWriter(cfg Config, level string) zapcore.WriteSyncer {
dir := filepath.Join(cfg.Dir, level)
_ = os.MkdirAll(dir, os.ModePerm)
return zapcore.AddSync(&lumberjack.Logger{
Filename: filepath.Join(dir, level+".log"),
MaxSize: cfg.MaxSize,
MaxBackups: cfg.MaxBackups,
MaxAge: cfg.MaxAge,
Compress: cfg.Compress,
})
}
// ======================
// level 解析
// ======================
func parseLevel(lvl string) zapcore.Level {
switch strings.ToLower(lvl) {
case "debug":
return zap.DebugLevel
case "warn":
return zap.WarnLevel
case "error":
return zap.ErrorLevel
default:
return zap.InfoLevel
}
}
// ======================
// trace 支持(核心)
// ======================
// Fiber 中使用
func Ctx(c fiber.Ctx) *zap.Logger {
if c == nil {
return Log
}
traceID, _ := c.Locals(TraceIDKey).(string)
if traceID == "" {
return Log
}
return Log.With(zap.String("trace_id", traceID))
}
// Service / Repo 使用
func FromCtx(ctx context.Context) *zap.Logger {
if ctx == nil {
return Log
}
traceID, _ := ctx.Value(TraceIDKey).(string)
if traceID == "" {
return Log
}
return Log.With(zap.String("trace_id", traceID))
}
// 注入 trace
func WithTrace(ctx context.Context, traceID string) context.Context {
return context.WithValue(ctx, TraceIDKey, traceID)
}
// ======================
// 优雅退出
// ======================
func Sync() {
if Log != nil {
_ = Log.Sync()
}
}