spark-server/internal/infrastructure/mysql/gorm_logger.go
zhr ae9a71034d feat: implement Spark IM V3 modular monolith
Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:52:11 +08:00

103 lines
2.4 KiB
Go

package mysql
import (
"context"
"errors"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
gormlogger "gorm.io/gorm/logger"
"spark-server/internal/infrastructure/logger"
"spark-server/internal/pkg/reqctx"
)
type gormZap struct {
base *zap.Logger
level gormlogger.LogLevel
slow time.Duration
}
func newGormLogger(base *zap.Logger, slow time.Duration, level gormlogger.LogLevel) *gormZap {
if base == nil {
base = zap.NewNop()
}
if slow <= 0 {
slow = 200 * time.Millisecond
}
if level == 0 {
level = gormlogger.Warn
}
return &gormZap{base: base.Named("gorm"), level: level, slow: slow}
}
func (l *gormZap) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
cp := *l
cp.level = level
return &cp
}
func (l *gormZap) Info(ctx context.Context, msg string, data ...interface{}) {
if l.level < gormlogger.Info {
return
}
l.zap(ctx).Sugar().Infof(msg, data...)
}
func (l *gormZap) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.level < gormlogger.Warn {
return
}
l.zap(ctx).Sugar().Warnf(msg, data...)
}
func (l *gormZap) Error(ctx context.Context, msg string, data ...interface{}) {
if l.level < gormlogger.Error {
return
}
l.zap(ctx).Sugar().Errorf(msg, data...)
}
func (l *gormZap) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.level <= gormlogger.Silent {
return
}
elapsed := time.Since(begin)
sql, rows := fc()
log := l.zap(ctx)
switch {
case err != nil && !errors.Is(err, gorm.ErrRecordNotFound) && l.level >= gormlogger.Error:
log.Error("sql", zap.Error(err), zap.String("sql", sql), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows))
case elapsed >= l.slow && l.level >= gormlogger.Warn:
log.Warn("sql_slow", zap.String("sql", sql), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows))
case l.level >= gormlogger.Info:
log.Info("sql", zap.String("sql", sql), zap.Duration("elapsed", elapsed), zap.Int64("rows", rows))
}
}
func (l *gormZap) zap(ctx context.Context) *zap.Logger {
if reqctx.From(ctx) != nil {
return logger.From(ctx).Named("gorm")
}
return l.base
}
func parseGormLevel(s, zapLevel string) gormlogger.LogLevel {
switch s {
case "silent":
return gormlogger.Silent
case "error":
return gormlogger.Error
case "warn", "warning":
return gormlogger.Warn
case "info":
return gormlogger.Info
default:
if zapLevel == "debug" {
return gormlogger.Info
}
return gormlogger.Warn
}
}