日志系统
GORM 集成
SlogLogger 适配器将 GORM 日志输出到 slog
GORM 集成
SlogLogger 是 GORM 日志适配器,实现 gorm.io/gorm/logger.Interface 接口,将数据库操作日志输出到 slog。
SlogLogger
type SlogLogger struct {
logger *slog.Logger
config GormLoggerConfig
slowThreshold time.Duration
logLevel LogLevel
ignoreRecordNotFoundError bool
}GormLoggerConfig
type GormLoggerConfig struct {
SlowThreshold int // 慢查询阈值(毫秒),超过此值以 WARN 级别记录
LogLevel LogLevel // 日志级别
IgnoreRecordNotFoundError bool // 是否忽略 ErrRecordNotFound 错误
Colorful bool // 是否启用彩色输出(预留字段)
}配置说明
字段
类型
日志级别
type LogLevel int
const (
LevelSilent LogLevel = iota + 1 // 静默模式,不输出任何日志
LevelError // 仅输出错误日志
LevelWarn // 输出错误和警告日志
LevelInfo // 输出所有级别日志(包括 SQL 语句)
)字段
类型
NewSlogLogger
创建 GORM slog 日志适配器:
func NewSlogLogger(slogger *slog.Logger, config GormLoggerConfig) logger.Interface参数说明:
slogger: slog.Logger 实例,推荐使用slog.Default().WithGroup(xLog.NamedREPO)config: GORM Logger 配置
示例:
gormLogger := xLog.NewSlogLogger(
slog.Default().WithGroup(xLog.NamedREPO),
xLog.GormLoggerConfig{
SlowThreshold: 200, // 200ms 慢查询阈值
LogLevel: xLog.LevelInfo, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略记录未找到错误
},
)日志输出规则
SQL 追踪
Trace 方法根据执行情况输出不同级别的日志:
func (l *SlogLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
switch {
// 执行出错 → ERROR 级别
case err != nil && l.logLevel >= LevelError:
l.logger.LogAttrs(ctx, slog.LevelError, "执行SQL语句失败", ...)
// 慢查询 → WARN 级别
case elapsed > l.slowThreshold && l.logLevel >= LevelWarn:
l.logger.LogAttrs(ctx, slog.LevelWarn, "发现SQL慢查询", ...)
// 普通查询 → DEBUG 级别
case l.logLevel >= LevelInfo:
l.logger.LogAttrs(ctx, slog.LevelDebug, "成功执行SQL语句", ...)
}
}日志属性
每条 SQL 日志包含以下属性:
字段
类型
使用示例
基础集成
func (r *Reg) DatabaseInit() {
dsn := "host=localhost user=postgres dbname=myapp"
// 创建 GORM Logger
gormLogger := xLog.NewSlogLogger(
slog.Default().WithGroup(xLog.NamedREPO),
xLog.GormLoggerConfig{
SlowThreshold: 200,
LogLevel: xLog.LevelInfo,
IgnoreRecordNotFoundError: true,
},
)
// 连接数据库
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: gormLogger,
})
if err != nil {
panic(err)
}
}环境区分
func createGormLogger(isDebug bool) logger.Interface {
config := xLog.GormLoggerConfig{
SlowThreshold: 200,
IgnoreRecordNotFoundError: true,
}
if isDebug {
config.LogLevel = xLog.LevelInfo // 开发环境:输出所有 SQL
} else {
config.LogLevel = xLog.LevelWarn // 生产环境:仅输出警告和错误
}
return xLog.NewSlogLogger(
slog.Default().WithGroup(xLog.NamedREPO),
config,
)
}链路追踪
GORM 操作自动继承 Context 中的 Trace ID:
func (r *UserRepo) FindByID(ctx context.Context, id int64) (*entity.User, error) {
var user entity.User
// WithContext 传递 Trace ID,日志会自动关联
err := r.db.WithContext(ctx).First(&user, id).Error
return &user, err
}日志输出:
2024-01-15 10:30:00.123 [DEBU] [abc123] [REPO] 成功执行SQL语句
elapsed_ms=1.234
rows=1
sql=SELECT * FROM users WHERE id = 12345 LIMIT 1慢查询监控
// 设置较低的阈值以捕获更多慢查询
gormLogger := xLog.NewSlogLogger(
slog.Default().WithGroup(xLog.NamedREPO),
xLog.GormLoggerConfig{
SlowThreshold: 100, // 100ms
LogLevel: xLog.LevelWarn,
},
)慢查询日志:
2024-01-15 10:30:00.123 [WARN] [abc123] [REPO] 发现SQL慢查询
elapsed_ms=156.789
rows=1000
sql=SELECT * FROM orders WHERE created_at > '2024-01-01'
threshold=100ms完整示例
package startup
import (
"log/slog"
"os"
xLog "github.com/bamboo-services/bamboo-base-go/common/log"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func InitDatabase() *gorm.DB {
dsn := os.Getenv("DATABASE_URL")
isDebug := os.Getenv("APP_ENV") == "development"
// 根据环境配置日志级别
logLevel := xLog.LevelWarn
if isDebug {
logLevel = xLog.LevelInfo
}
gormLogger := xLog.NewSlogLogger(
slog.Default().WithGroup(xLog.NamedREPO),
xLog.GormLoggerConfig{
SlowThreshold: 200,
LogLevel: logLevel,
IgnoreRecordNotFoundError: true,
},
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: gormLogger,
})
if err != nil {
panic(err)
}
return db
}