使用logrus记录gorm|使用logrus记录gorm sql

【使用logrus记录gorm|使用logrus记录gorm sql】gorm可以方便的输出执行的sql或慢查询。logrus是常用的日志组件,如何将gorm输出的sql通过logrus记录到日志中呢?
1. 代码实现 我们先看代码。
思路:使用logrus,实现gorm/logger.Writer接口

var DB *gorm.DB//定义自己的Writer type MyWriter struct { mlog *logrus.Logger }//实现gorm/logger.Writer接口 func (m *MyWriter)Printf(format string , v ...interface{}){ logstr:= fmt.Sprintf(format, v...) //利用loggus记录日志 m.mlog.Info(logstr) }func NewMyWriter() *MyWriter{ log := logrus.New() //配置logrus log.SetFormatter(&logrus.JSONFormatter{ TimestampFormat:"2006-01-02 15:04:05", })return &MyWriter{mlog:log} }//DB初始化 func Init() error { var err error dsn := "root:user237@tcp(10.160.75.237:3306)/mydb?charset=utf8&parseTime=true&loc=Local"slowLogger := logger.New( //设置Logger NewMyWriter(), logger.Config{ //慢SQL阈值 SlowThreshold: time.Millisecond, //设置日志级别,只有Warn以上才会打印sql LogLevel:logger.Warn, }, )DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger:slowLogger, })return err }... ...func main(){ //初始化 _ = Init()d := User{ Name:"ball", Age:0, IsAdmin:true, IsValid:false, LoginTime:time.Now(), }DB.Create(&d) }

输出
{"level":"info","msg":"/home/ballqiu/go/gorm/main.go:90 SLOW SQL \u003e= 1ms\n[4.333ms] [rows:1] INSERT INTO `User` (`name`,`age`,`is_admin`,`is_valid`,`login_time`) VALUES ('ball',0,true,false,'2021-05-14 18:58:17.857')","time":"2021-05-14 18:58:17"}

如果你将logrus配置输出至文件,日志就会写入文件中。
2. 代码解读 在作详细说明之前,先来看下上述代码使用到的interface和struct之间的关系。

使用logrus记录gorm|使用logrus记录gorm sql
文章图片
image
  • gorm.Open()的第二参数为Option接口,因为gorm.Config实现了该接口,因此可以作为参数传入。
/*gorm.go*/func Open(dialector Dialector, opts ...Option) (db *DB, err error)

  • gorm.Config包含Logger成员,该成员为logger.Interface类型。logger.New()返回的是一个struct logger实例,它实现了Interface接口,因此可以赋值给gorm.Config.Logger。
slowLogger := logger.New() DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger:slowLogger, })

  • logger.New的第一参数为logger.Writer接口,我们的MyWriter实现了该接口,因此可以传入。
/*gorm/logger/logger.go*/func New(writer Writer, config Config) Interface { ...// return &logger{ //传入的writer在此处赋给了logger Writer:writer, Config:config, infoStr:infoStr, warnStr:warnStr, errStr:errStr, traceStr:traceStr, traceWarnStr: traceWarnStr, traceErrStr:traceErrStr, } }type Writer interface { Printf(string, ...interface{}) }

  • logger.** 在输出时调用了Printf(Writer接口),也就是我们自己的MyWriter.Printf,因此日志得以写入logrus
/*gorm/logger/logger.go*/ func (l logger) Info(ctx context.Context, msg string, data ...interface{}) { if l.LogLevel >= Info { l.Printf(l.infoStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) } }

    推荐阅读