66 lines
2.0 KiB
Go
66 lines
2.0 KiB
Go
package data
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
// gormLogger forwards GORM diagnostics through the application logger so SQL
|
|
// entries participate in the same daily/category files and error sink as the
|
|
// rest of the service. Slow queries use the administration contract's 200ms
|
|
// threshold.
|
|
type gormLogger struct {
|
|
logger *slog.Logger
|
|
slowThreshold time.Duration
|
|
level logger.LogLevel
|
|
}
|
|
|
|
func newGormLogger(log *slog.Logger, level logger.LogLevel) *gormLogger {
|
|
if log == nil {
|
|
log = slog.New(slog.NewTextHandler(io.Discard, nil))
|
|
}
|
|
return &gormLogger{logger: log, slowThreshold: 200 * time.Millisecond, level: level}
|
|
}
|
|
|
|
func (g *gormLogger) LogMode(level logger.LogLevel) logger.Interface {
|
|
next := *g
|
|
next.level = level
|
|
return &next
|
|
}
|
|
|
|
func (g *gormLogger) Info(ctx context.Context, message string, args ...any) {
|
|
g.logger.InfoContext(ctx, fmt.Sprintf(message, args...), "mod", "sql", "gorm_logger", true)
|
|
}
|
|
|
|
func (g *gormLogger) Warn(ctx context.Context, message string, args ...any) {
|
|
g.logger.WarnContext(ctx, fmt.Sprintf(message, args...), "mod", "sql", "gorm_logger", true)
|
|
}
|
|
|
|
func (g *gormLogger) Error(ctx context.Context, message string, args ...any) {
|
|
g.logger.ErrorContext(ctx, fmt.Sprintf(message, args...), "mod", "sql", "gorm_logger", true)
|
|
}
|
|
|
|
func (g *gormLogger) Trace(ctx context.Context, begin time.Time, query func() (string, int64), queryErr error) {
|
|
if g.level <= logger.Silent {
|
|
return
|
|
}
|
|
elapsed := time.Since(begin)
|
|
sql, rows := query()
|
|
fields := []any{"mod", "sql", "gorm_logger", true, "sql", sql, "rows", rows, "elapsed_ms", elapsed.Milliseconds()}
|
|
switch {
|
|
case queryErr != nil && g.level >= logger.Error && !errors.Is(queryErr, logger.ErrRecordNotFound):
|
|
fields = append(fields, "error", queryErr)
|
|
g.logger.ErrorContext(ctx, "SQL 执行错误", fields...)
|
|
case elapsed > g.slowThreshold && g.level >= logger.Warn:
|
|
g.logger.WarnContext(ctx, "SQL 慢查询", fields...)
|
|
case g.level >= logger.Info:
|
|
g.logger.InfoContext(ctx, "SQL", fields...)
|
|
}
|
|
}
|