58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
gormlogger "gorm.io/gorm/logger"
|
|
)
|
|
|
|
type structuredGORMLogger struct {
|
|
logger *slog.Logger
|
|
level gormlogger.LogLevel
|
|
slowThreshold time.Duration
|
|
}
|
|
|
|
func newStructuredGORMLogger(logger *slog.Logger) gormlogger.Interface {
|
|
return structuredGORMLogger{logger: logger, level: gormlogger.Warn, slowThreshold: 500 * time.Millisecond}
|
|
}
|
|
|
|
func (l structuredGORMLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
|
|
l.level = level
|
|
return l
|
|
}
|
|
|
|
func (l structuredGORMLogger) Info(_ context.Context, message string, args ...any) {
|
|
if l.level >= gormlogger.Info {
|
|
l.logger.Info("gorm", "message", message, "args", args)
|
|
}
|
|
}
|
|
|
|
func (l structuredGORMLogger) Warn(_ context.Context, message string, args ...any) {
|
|
if l.level >= gormlogger.Warn {
|
|
l.logger.Warn("gorm", "message", message, "args", args)
|
|
}
|
|
}
|
|
|
|
func (l structuredGORMLogger) Error(_ context.Context, message string, args ...any) {
|
|
if l.level >= gormlogger.Error {
|
|
l.logger.Error("gorm", "message", message, "args", args)
|
|
}
|
|
}
|
|
|
|
func (l structuredGORMLogger) Trace(_ context.Context, begin time.Time, query func() (sql string, rowsAffected int64), err error) {
|
|
elapsed := time.Since(begin)
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) && l.level >= gormlogger.Error {
|
|
_, rows := query()
|
|
l.logger.Error("database query failed", "error", err, "rows", rows, "duration_ms", elapsed.Milliseconds())
|
|
return
|
|
}
|
|
if elapsed > l.slowThreshold && l.level >= gormlogger.Warn {
|
|
_, rows := query()
|
|
l.logger.Warn("slow database query", "rows", rows, "duration_ms", elapsed.Milliseconds())
|
|
}
|
|
}
|