This commit is contained in:
oneao committed 2026-04-02 22:07:21 +08:00
1 parent ae0d245605
commit 4725ee75ca
26 files changed
+1089 -67

No files matched your search

@@ -0,0 +1,170 @@
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()
}
}