log包改造
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/config"
|
||||
@@ -32,6 +33,11 @@ const (
|
||||
bold = "\033[1m"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultLogger *Logger
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// Logger 是一个封装了 zap.SugaredLogger 的日志记录器。
|
||||
// 它提供了结构化日志记录的各种方法,并实现了 io.Writer 接口以兼容 Gin。
|
||||
type Logger struct {
|
||||
@@ -64,10 +70,51 @@ func NewLogger(cfg config.LogConfig) *Logger {
|
||||
return &Logger{zapLogger.Sugar()}
|
||||
}
|
||||
|
||||
// InitDefaultLogger 初始化包级单例的 defaultLogger。
|
||||
// 此函数应在应用程序启动时调用一次。
|
||||
func InitDefaultLogger(cfg config.LogConfig) {
|
||||
once.Do(func() {
|
||||
defaultLogger = NewLogger(cfg)
|
||||
})
|
||||
}
|
||||
|
||||
// GetLogger 从 Context 中提取调用链信息,并返回一个携带这些信息的 Logger 副本。
|
||||
// 如果 Context 中没有调用链信息,则直接返回默认的 Logger。
|
||||
func GetLogger(ctx context.Context) *Logger {
|
||||
if defaultLogger == nil {
|
||||
// 在调用 InitDefaultLogger 之前,提供一个备用的、仅输出到控制台的 Logger
|
||||
fallbackCfg := config.LogConfig{Level: "info", Format: "console"}
|
||||
return NewLogger(fallbackCfg)
|
||||
}
|
||||
|
||||
val := ctx.Value(chainKey)
|
||||
if val == nil {
|
||||
return defaultLogger
|
||||
}
|
||||
|
||||
chain, ok := val.([]string)
|
||||
if !ok || len(chain) == 0 {
|
||||
return defaultLogger
|
||||
}
|
||||
|
||||
// 使用 With 方法创建带有 "trace" 字段的 Logger 副本
|
||||
newSugaredLogger := defaultLogger.With("trace", strings.Join(chain, "->"))
|
||||
return &Logger{newSugaredLogger}
|
||||
}
|
||||
|
||||
// Trace 是构建和记录调用链的核心函数。
|
||||
// 它首先使用 AddFuncName 创建一个包含新调用节点的新 Context,
|
||||
// 然后返回这个新 Context 和一个包含完整调用链的 Logger 实例。
|
||||
func Trace(upstreamCtx context.Context, selfCtx context.Context, funcName string) (context.Context, *Logger) {
|
||||
newCtx := AddFuncName(upstreamCtx, selfCtx, funcName)
|
||||
logger := GetLogger(newCtx)
|
||||
return newCtx, logger
|
||||
}
|
||||
|
||||
// GetEncoder 根据指定的格式返回一个 zapcore.Encoder。
|
||||
func GetEncoder(format string) zapcore.Encoder {
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 时间格式: 2006-01-02T15:04:05.000Z0700
|
||||
encoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder // 时间格式: 2006-01-02T15:04:05Z07:00
|
||||
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder // 日志级别大写: INFO (由 coloredConsoleEncoder 处理颜色)
|
||||
|
||||
if format == "json" {
|
||||
@@ -190,17 +237,17 @@ func (g *GormLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
|
||||
|
||||
// Info 打印 Info 级别的日志。
|
||||
func (g *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
|
||||
g.ZapLogger.Infof(msg, data...)
|
||||
GetLogger(ctx).Infof(msg, data...)
|
||||
}
|
||||
|
||||
// Warn 打印 Warn 级别的日志。
|
||||
func (g *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
|
||||
g.ZapLogger.Warnf(msg, data...)
|
||||
GetLogger(ctx).Warnf(msg, data...)
|
||||
}
|
||||
|
||||
// Error 打印 Error 级别的日志。
|
||||
func (g *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
|
||||
g.ZapLogger.Errorf(msg, data...)
|
||||
GetLogger(ctx).Errorf(msg, data...)
|
||||
}
|
||||
|
||||
// Trace 打印 SQL 查询日志,这是 GORM 日志的核心。
|
||||
@@ -214,25 +261,27 @@ func (g *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql
|
||||
"elapsed", fmt.Sprintf("%.3fms", float64(elapsed.Nanoseconds())/1e6),
|
||||
}
|
||||
|
||||
// --- 逻辑修复开始 ---
|
||||
// 获取带有调用链的 logger
|
||||
logger := GetLogger(ctx)
|
||||
|
||||
if err != nil {
|
||||
// 如果是 "record not found" 错误且我们配置了跳过,则直接返回
|
||||
if g.SkipErrRecordNotFound && strings.Contains(err.Error(), "record not found") {
|
||||
return
|
||||
}
|
||||
// 否则,记录为错误日志
|
||||
g.ZapLogger.With(fields...).Errorf("[GORM] error: %s", err)
|
||||
logger.With(fields...).Errorf("[GORM] error: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果查询时间超过慢查询阈值,则记录警告
|
||||
if g.SlowThreshold != 0 && elapsed > g.SlowThreshold {
|
||||
g.ZapLogger.With(fields...).Warnf("[GORM] slow query")
|
||||
logger.With(fields...).Warnf("[GORM] slow query")
|
||||
return
|
||||
}
|
||||
|
||||
// 正常情况,记录 Debug 级别的 SQL 查询
|
||||
g.ZapLogger.With(fields...).Debugf("[GORM] trace")
|
||||
logger.With(fields...).Debugf("[GORM] trace")
|
||||
// --- 逻辑修复结束 ---
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user