sequence

This article focuses on gorM logger

logger

Gorm. IO/[email protected] / logger/logger. Go

type logger struct { Writer Config infoStr, warnStr, errStr string traceStr, traceErrStr, traceWarnStr string } type Writer interface { Printf(string, ... interface{}) } type Config struct { SlowThreshold time.Duration Colorful bool LogLevel LogLevel }Copy the code

The Logger has built-in Writer, Config, info, WARN, Err, trace, traceErr, and traceWarn attributes

logger.New

Gorm. IO/[email protected] / logger/logger. Go

func New(writer Writer, config Config) Interface { var ( infoStr = "%s\n[info] " warnStr = "%s\n[warn] " errStr = "%s\n[error] " traceStr = "%s\n[%.3fms] [rows:%v] %s" traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s" traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s" )  if config.Colorful { infoStr = Green + "%s\n" + Reset + Green + "[info] " + Reset warnStr = BlueBold + "%s\n" + Reset +  Magenta + "[warn] " + Reset errStr = Magenta + "%s\n" + Reset + Red + "[error] " + Reset traceStr = Green + "%s\n" + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s" traceWarnStr = Green + "%s " + Yellow + "%s\n" + Reset + RedBold + "[%.3fms] " + Yellow + "[rows:%v]" + Magenta + " %s" + Reset traceErrStr = RedBold + "%s " + MagentaBold + "%s\n" + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s" } return &logger{ Writer: writer, Config: config, infoStr: infoStr, warnStr: warnStr, errStr: errStr, traceStr: traceStr, traceWarnStr: traceWarnStr, traceErrStr: traceErrStr, } }Copy the code

Logger. New creates a logger based on config

Interface

// Interface logger interface type Interface interface { LogMode(LogLevel) Interface Info(context.Context, string, ... interface{}) Warn(context.Context, string, ... interface{}) Error(context.Context, string, ... interface{}) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) }Copy the code

The logger.Interface Interface defines LogMode, Info, Warn, Error, and Trace methods

LogMode

// LogMode log mode func (l *logger) LogMode(level LogLevel) Interface { newlogger := *l newlogger.LogLevel = level return &newlogger } // Info print info 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...) ...). } } // Warn print warn messages func (l logger) Warn(ctx context.Context, msg string, data ... interface{}) { if l.LogLevel >= Warn { l.Printf(l.warnStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...) ...). } } // Error print error messages func (l logger) Error(ctx context.Context, msg string, data ... interface{}) { if l.LogLevel >= Error { l.Printf(l.errStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...) ...). } } // Trace print sql message func (l logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { if l.LogLevel > Silent { elapsed := time.Since(begin) switch { case err ! = nil && l.LogLevel >= Error: sql, rows := fc() if rows == -1 { l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) } case elapsed > l.SlowThreshold && l.SlowThreshold ! = 0 && l.LogLevel >= Warn: sql, rows := fc() slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold) if rows == -1 { l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) } default: sql, rows := fc() if rows == -1 { l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) } else { l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) } } } }Copy the code

Logger implements the LogMode, Info, Warn, Error, and Trace methods defined by logger.Interface

Session.Logger

Gorm. IO/[email protected] / gorm. Go

type Session struct {
	DryRun                   bool
	PrepareStmt              bool
	NewDB                    bool
	SkipHooks                bool
	SkipDefaultTransaction   bool
	DisableNestedTransaction bool
	AllowGlobalUpdate        bool
	FullSaveAssociations     bool
	QueryFields              bool
	Context                  context.Context
	Logger                   logger.Interface
	NowFunc                  func() time.Time
	CreateBatchSize          int
}
Copy the code

Logger defines Logger attributes, which are finally set to db.logger

callback

Gorm. IO/[email protected] / callbacks. Go

func (c *callback) Remove(name string) error {
	c.processor.db.Logger.Warn(context.Background(), "removing callback `%v` from %v\n", name, utils.FileWithLineNum())
	c.name = name
	c.remove = true
	c.processor.callbacks = append(c.processor.callbacks, c)
	return c.processor.compile()
}

func (c *callback) Replace(name string, fn func(*DB)) error {
	c.processor.db.Logger.Info(context.Background(), "replacing callback `%v` from %v\n", name, utils.FileWithLineNum())
	c.name = name
	c.handler = fn
	c.replace = true
	c.processor.callbacks = append(c.processor.callbacks, c)
	return c.processor.compile()
}
Copy the code

The Remove, Replace, and other callback methods print using db.Logger

The instance

func loggerDemo() { newLogger := logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), // IO writer logger.Config{SlowThreshold: time.Second, // slow SQL threshold LogLevel: logger.Silent, // Log level Colorful: Db, err := gorm.Open(sqlite.open ("test.db"), &gorm.Config{Logger: newLogger,}) if err! = nil { panic(err) } if err := db.AutoMigrate(&User{}); err ! Session(&gorm.Session{Logger: newLogger}) user := user {Name: "Tom", Age: = nil {panic(err)} // New Session mode tx := db.session (&gorm.Session{Logger: newLogger}) user := user {Name: "Tom", Age: 18, Birthday: time.Now()} result := db.Create(&user) // pass pointer of data to Create log.Println("userId:", user.ID) log.Println("result.RowsAffected:", result.RowsAffected, "result.Error:", result.Error) tx.First(&user) log.Printf("%+v", user) tx.Model(&user).Update("Age", 18) }Copy the code

The output

2021/01/10 23:32:42 userId: 6
2021/01/10 23:32:42 result.RowsAffected: 1 result.Error: <nil>
2021/01/10 23:32:42 {ID:6 Name:Tom Age:18 Birthday:2021-01-10 23:32:42.818057 +0800 +0800 DeletedAt:<nil> CreatedAt:2021-01-10 23:32:42.818107 +0800 +0800 UpdatedAt:2021-01-10 23:32:42.818107 +0800 +0800}
Copy the code

summary

Gorm logger provides an Interface, which can be implemented and set globally or at the session level. The default LOGGER in GORM implements the LogMode, Info, Warn, Error, and Trace methods defined by the Logger. Interface Interface.

doc

  • gorm