需在 gorm.Config 中配置 logger.Default.LogMode(logger.Info),仅设 LogMode 或用 Debug() 不足;v2 必须初始化 Logger 实例并传入 gorm.New,否则无 SQL 输出。

怎么让 GORM 打印出执行的 SQL?
默认情况下,GORM 完全不输出任何 SQL,不是它没执行,是日志开关关着。关键就一个配置点:Logger 实例,不是简单设个布尔值。
常见错误现象:DB.Debug().First(&user) 看起来像开启了调试,但只对单次调用生效,且不打印参数值(比如 WHERE id = ? 后面的 1 还是看不到);或者直接写 gorm.Config{Logger: logger} 却忘了初始化 logger,结果静默失败。
- 必须用
gorm.New()创建 DB 时传入完整配置,不能靠后期覆盖 - 推荐用
logger.Default.LogMode(logger.Info),不是logger.Silent或空结构体 - 如果用了
gorm.Open(mysql.Open(dsn), &gorm.Config{...}),Config里必须显式配Logger
GORM v2 日志级别和参数绑定怎么开?
v2 默认只打基础 SQL 模板(带 ? 占位符),不展开实际参数——这会让排查“为什么查不到数据”变得困难。要看到真实值,得调高日志级别并启用参数解析。
性能影响很小,仅在开发/测试环境开启;生产环境切回 logger.Warn 或 logger.Error 即可。
立即学习“go语言免费学习笔记(深入)”;
-
logger.Info:显示 SQL + 参数(如SELECT * FROM users WHERE id = 1) -
logger.Warn:只显示 SQL 模板(如SELECT * FROM users WHERE id = ?) - 必须配合
.LogMode(logger.Info),光设Config.Logger不够 - 注意:参数展开依赖驱动是否支持
Rows.Columns(),SQLite 和 MySQL 通常 OK,某些旧版 PostgreSQL 驱动可能不显示
自定义 GORM 日志输出到文件或加前缀?
直接用 logger.Default 会混在 stdout,不方便过滤。想写文件、加时间戳、或者区分模块,就得自己造 logger.Interface。
容易踩的坑:实现 LogMode 方法时返回了新 struct 但没保存 level 字段,导致后续调用始终是默认级别;或者用 fmt.Printf 写文件却没加锁,多 goroutine 下日志错乱。
- 最简自定义:包装
logger.Default,重写Info/Warn方法,开头加[gorm] - 写文件:用
log.New(os.File, "", log.LstdFlags)构造,传给logger.New()的第三个参数 - 别直接替换
logger.Default全局实例,不同 DB 实例该用各自 logger - 示例关键行:
l := logger.New(log.New(os.Stdout, "[gorm] ", log.LstdFlags), logger.Config{LogLevel: logger.Info})
为什么开了日志还是没看到 SQL?
不是配置没生效,大概率是 SQL 根本没发出去——GORM 的链式调用是惰性的,Find/First 之前漏了 Where 或拼错了 struct tag,导致生成空 SQL 或提前 panic。
另一个高频原因:你改的是旧版 GORM(v1)的配置方式,但项目实际用的是 v2,接口已变。
- 检查
go.mod里gorm.io/gorm版本,v1 是gopkg.in/gorm.v1 - 确认
gorm.Open()返回 error 是否被忽略,失败时DB是 nil,后续调用静默跳过 - 用
DB.Session(&Session{DryRun: true})先试跑,看能否生成 SQL 字符串,排除语法问题 - 如果用
WithContext(ctx),确保 ctx 没被 cancel,否则查询中途退出,日志也不输出
SQL 日志不是万能探针,它只反映“GORM 认为该发什么”,不保证数据库真收到了——网络、权限、连接池耗尽这些层的问题,得看数据库侧日志。


















