Files

80 lines
2.2 KiB
Go

package db
import (
"context"
"errors"
"fmt"
"time"
"github.com/sirupsen/logrus"
"gorm.io/gorm/logger"
)
type safeLogger struct {
logger.Config
}
func newSafeLogger() logger.Interface {
return &safeLogger{Config: logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Warn,
IgnoreRecordNotFoundError: false,
}}
}
func (l *safeLogger) LogMode(level logger.LogLevel) logger.Interface {
newLogger := *l
newLogger.LogLevel = level
return &newLogger
}
func (l *safeLogger) Info(ctx context.Context, _ string, _ ...interface{}) {
if l.LogLevel >= logger.Info {
logrus.WithContext(ctx).WithField("component", "gorm").Info("数据库信息事件")
}
}
func (l *safeLogger) Warn(ctx context.Context, _ string, _ ...interface{}) {
if l.LogLevel >= logger.Warn {
logrus.WithContext(ctx).WithField("component", "gorm").Warn("数据库警告事件")
}
}
func (l *safeLogger) Error(ctx context.Context, _ string, _ ...interface{}) {
if l.LogLevel >= logger.Error {
logrus.WithContext(ctx).WithField("component", "gorm").Error("数据库错误事件")
}
}
func (l *safeLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel <= logger.Silent {
return
}
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= logger.Error && (!errors.Is(err, logger.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError):
_, rows := fc()
l.traceEntry(ctx, elapsed, rows).WithFields(logrus.Fields{
"error_type": fmt.Sprintf("%T", err),
"record_not_found": errors.Is(err, logger.ErrRecordNotFound),
}).Error("数据库操作失败")
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
_, rows := fc()
l.traceEntry(ctx, elapsed, rows).
WithField("slow_threshold", l.SlowThreshold.String()).
Warn("数据库慢查询")
case l.LogLevel >= logger.Info:
_, rows := fc()
l.traceEntry(ctx, elapsed, rows).Info("数据库操作完成")
}
}
func (l *safeLogger) traceEntry(ctx context.Context, elapsed time.Duration, rows int64) *logrus.Entry {
return logrus.WithContext(ctx).WithFields(logrus.Fields{
"component": "gorm",
"elapsed_ms": float64(elapsed.Nanoseconds()) / 1e6,
"rows_affected": rows,
})
}