
本文介绍如何在 gorm 中按环境(如仅开发环境)自动启用 sql 查询日志,避免在生产环境误开调试日志,同时兼容预加载(preload)等复杂查询场景。
本文介绍如何在 gorm 中按环境(如仅开发环境)自动启用 sql 查询日志,避免在生产环境误开调试日志,同时兼容预加载(preload)等复杂查询场景。
在 Go 应用中使用 GORM 操作数据库时,调试阶段常需查看实际生成的 SQL 语句以排查性能或逻辑问题。GORM 提供了 LogMode 方法用于全局控制 SQL 日志输出——与链式调用的 Debug() 不同,LogMode(true) 是连接级别的设置,对所有后续操作(包括 Find、Preload、Create 等)均生效,且只需配置一次。
✅ 正确启用方式(推荐)
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"os"
)
func initDB() (*gorm.DB, error) {
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
// 仅在开发环境启用 SQL 日志(通过环境变量控制)
if os.Getenv("ENV") == "dev" || os.Getenv("GIN_MODE") == "debug" {
sqlDB, err := db.DB()
if err != nil {
log.Printf("failed to get underlying sql.DB: %v", err)
return nil, err
}
// 启用 GORM 内置日志器(输出到标准输出)
db.Logger = logger.Default.LogMode(logger.Info)
// 或更底层:直接设置 sql.DB 的日志(不推荐,GORM v2+ 推荐用 Logger)
// 注意:GORM v2 中 LogMode 已被弃用,应使用 Logger 配置
}
return db, nil
}
⚠️ 注意:GORM v2(即 gorm.io/gorm)已移除 LogMode() 方法,原答案中 db.LogMode(true) 适用于 GORM v1(github.com/jinzhu/gorm)。若你使用的是 GORM v2,请改用 Logger 配置:
import "gorm.io/gorm/logger"
// 开发环境:启用详细 SQL 日志(含参数、执行时间)
if os.Getenv("ENV") == "dev" {
newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
Colorful: true, // 启用颜色
},
)
db.Logger = newLogger
}
? 验证效果
启用后,以下代码将自动打印完整 SQL(含 JOIN 和预加载语句):
db.Preload("User").Find(&todos)
// 输出示例:
// SELECT * FROM `todos` ...
// SELECT * FROM `users` WHERE `users`.`id` IN (1,2,3)
✅ 最佳实践建议
- ✅ 使用环境变量(如 ENV=dev)而非硬编码判断,便于 Docker/K8s 部署;
- ✅ 生产环境务必禁用 logger.Info 级别日志,可降级为 logger.Warn 或 logger.Error;
- ✅ 避免在生产环境使用 logger.Info + SlowThreshold=0,以防日志爆炸;
- ✅ 若需自定义日志格式(如接入 ELK),可实现 logger.Interface 接口。
通过合理配置 Logger,你既能获得开发期所需的透明 SQL 能力,又能确保生产环境零日志开销与安全合规。











