目录
- [1. 使用 Debug 方法](#1. 使用 Debug 方法)
 - [2. 全局设置日志级别](#2. 全局设置日志级别)
 - [3. 自定义 Logger](#3. 自定义 Logger)
 - [4. 总结](#4. 总结)
 
参考 gorm 文档:https://gorm.io/zh_CN/docs/logger.html
Gorm 有一个 默认 logger 实现,默认情况下,它会打印慢 SQL 和错误。如果想要全部或部分打印 SQL 的话可以通过设置日志级别和使用 Logger 接口来实现自定义处理。以下是一些方法来实现这个功能。
1. 使用 Debug 方法
GORM 提供了一个 Debug 方法,可以在链式调用中打印出生成的 SQL 语句和执行时间。
一般用于开发或者是线上排查某个问题时使用。
Debug 单个操作时,会将当前操作的 log 级别调整为
logger.Info
代码示例:
            
            
              go
              
              
            
          
          package main
import (
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)
type User struct {
    ID   int
    Name string
}
func main() {
    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 {
        panic("failed to connect database")
    }
    var users []User
    // 使用 Debug() 方法
    db.Debug().Where("name = ?", "John").Find(&users)
    fmt.Println(users)
}
        2. 全局设置日志级别
在 GORM 配置中设置 Logger,可以全局打印 SQL 语句。可以使用 gorm/logger 包来设置日志级别。
GORM 定义了这些日志级别:
Silent:不打印任何日志。Error:仅打印错误日志。Warn:打印警告和错误日志。Info:打印所有日志(包括 SQL 语句和运行时间)
代码示例:
            
            
              go
              
              
            
          
          package main
import (
    "log"
    "time"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)
type User struct {
    ID   int
    Name string
}
func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    newLogger := logger.New(
        log.New(log.Writer(), "\r\n", log.LstdFlags), // io writer
        logger.Config{
            SlowThreshold: time.Second,   // 慢 SQL 阈值
            LogLevel:      logger.Info,   // 日志级别
            IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
            Colorful:      true,          // 启用彩色打印
        },
    )
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
        Logger: newLogger,
    })
    if err != nil {
        panic("failed to connect database")
    }
    var users []User
    db.Where("name = ?", "John").Find(&users)
    fmt.Println(users)
}
        3. 自定义 Logger
如果需要更复杂的日志逻辑,可以实现 gorm/logger 包中的 Interface 接口,来自定义 Logger。
参考 GORM 的 默认 logger 来定义您自己的 logger
代码示例:
            
            
              go
              
              
            
          
          package main
import (
    "log"
    "time"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
    "gorm.io/gorm/utils"
)
type CustomLogger struct {
    logger.Interface
}
func (c *CustomLogger) Info(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[INFO] "+msg, data...)
}
func (c *CustomLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[WARN] "+msg, data...)
}
func (c *CustomLogger) Error(ctx context.Context, msg string, data ...interface{}) {
    log.Printf("[ERROR] "+msg, data...)
}
// 追踪并输出 sql 的详细信息:sql 语句、绑定的参数、执行时间等。
func (c *CustomLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
    elapsed := time.Since(begin)
    sql, rows := fc()
    log.Printf("[SQL] %s [rows:%d] [elapsed:%s] [error:%v]\n", sql, rows, elapsed, err)
}
func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    customLogger := &CustomLogger{}
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
        Logger: customLogger,
    })
    if err != nil {
        panic("failed to connect database")
    }
    var users []User
    db.Where("name = ?", "John").Find(&users)
    fmt.Println(users)
}
        4. 总结
通过上述方法,可以在 GORM 中实现 SQL 语句的打印,从而方便调试和监控数据库操作。根据具体需求,可以选择使用 Debug 模式、全局设置日志级别或者自定义 Logger。