Refactor logger

This commit is contained in:
Jinzhu 2020-02-23 15:07:47 +08:00
parent c3b798aec8
commit 27cb613871
4 changed files with 97 additions and 28 deletions

View File

@ -90,9 +90,9 @@ func (p *processor) Execute(db *DB) {
} }
if stmt := db.Statement; stmt != nil { if stmt := db.Statement; stmt != nil {
db.Logger.RunWith(logger.Info, func() { db.Logger.Trace(curTime, func() (string, int64) {
db.Logger.Info(db.Dialector.Explain(stmt.SQL.String(), stmt.Vars)) return db.Dialector.Explain(stmt.SQL.String(), stmt.Vars), db.RowsAffected
}) }, db.Error)
} }
} }

View File

@ -1,14 +1,29 @@
package logger package logger
import ( import (
"fmt"
"log" "log"
"os" "os"
"time"
"github.com/jinzhu/gorm/utils"
) )
type LogLevel int // Colors
const (
Reset = "\033[0m"
Red = "\033[31m"
Green = "\033[32m"
Yellow = "\033[33m"
Blue = "\033[34m"
Magenta = "\033[35m"
Cyan = "\033[36m"
White = "\033[37m"
Redbold = "\033[31;1m"
YellowBold = "\033[33;1m"
)
var Default Interface = Logger{Writer: log.New(os.Stdout, "\r\n", log.LstdFlags)} // LogLevel
type LogLevel int
const ( const (
Error LogLevel = iota + 1 Error LogLevel = iota + 1
@ -16,52 +31,101 @@ const (
Info Info
) )
// Writer log writer interface
type Writer interface {
Printf(string, ...interface{})
}
type Config struct {
SlowThreshold time.Duration
Colorful bool
LogLevel LogLevel
}
// Interface logger interface // Interface logger interface
type Interface interface { type Interface interface {
LogMode(LogLevel) Interface LogMode(LogLevel) Interface
Info(string, ...interface{}) Info(string, ...interface{})
Warn(string, ...interface{}) Warn(string, ...interface{})
Error(string, ...interface{}) Error(string, ...interface{})
RunWith(LogLevel, func()) Trace(begin time.Time, fc func() (string, int64), err error)
} }
// Writer log writer interface var Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), Config{
type Writer interface { SlowThreshold: 100 * time.Millisecond,
Print(...interface{}) Colorful: true,
})
func New(writer Writer, config Config) Interface {
var (
infoPrefix = "%s\n[info] "
warnPrefix = "%s\n[warn] "
errPrefix = "%s\n[error] "
tracePrefix = "%s\n[%v] [rows:%d] %s"
traceErrPrefix = "%s\n[%v] [rows:%d] %s"
)
if config.Colorful {
infoPrefix = Green + "%s\n" + Reset + Green + "[info]" + Reset
warnPrefix = Blue + "%s\n" + Reset + Magenta + "[warn]" + Reset
errPrefix = Magenta + "%s\n" + Reset + Red + "[error]" + Reset
tracePrefix = Green + "%s\n" + Reset + YellowBold + "[%.3fms] " + Green + "[rows:%d]" + Reset + " %s"
traceErrPrefix = Magenta + "%s\n" + Reset + Redbold + "[%.3fms] " + Yellow + "[rows:%d]" + Reset + " %s"
}
return logger{
Writer: writer,
Config: config,
infoPrefix: infoPrefix,
warnPrefix: warnPrefix,
errPrefix: errPrefix,
tracePrefix: tracePrefix,
traceErrPrefix: traceErrPrefix,
}
} }
type Logger struct { type logger struct {
Writer Writer
logLevel LogLevel Config
infoPrefix, warnPrefix, errPrefix string
tracePrefix, traceErrPrefix string
} }
func (logger Logger) LogMode(level LogLevel) Interface { // LogMode log mode
return Logger{Writer: logger.Writer, logLevel: level} func (l logger) LogMode(level LogLevel) Interface {
config := l.Config
config.LogLevel = level
return logger{Writer: l.Writer, Config: config}
} }
// Info print info // Info print info
func (logger Logger) Info(msg string, data ...interface{}) { func (l logger) Info(msg string, data ...interface{}) {
if logger.logLevel >= Info { if l.LogLevel >= Info {
logger.Print("[info] " + fmt.Sprintf(msg, data...)) l.Printf(l.infoPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...))
} }
} }
// Warn print warn messages // Warn print warn messages
func (logger Logger) Warn(msg string, data ...interface{}) { func (l logger) Warn(msg string, data ...interface{}) {
if logger.logLevel >= Warn { if l.LogLevel >= Warn {
logger.Print("[warn] " + fmt.Sprintf(msg, data...)) l.Printf(l.warnPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...))
} }
} }
// Error print error messages // Error print error messages
func (logger Logger) Error(msg string, data ...interface{}) { func (l logger) Error(msg string, data ...interface{}) {
if logger.logLevel >= Error { if l.LogLevel >= Error {
logger.Print("[error] " + fmt.Sprintf(msg, data...)) l.Printf(l.errPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...))
} }
} }
func (logger Logger) RunWith(logLevel LogLevel, fc func()) { // Trace print sql message
if logger.logLevel >= logLevel { func (l logger) Trace(begin time.Time, fc func() (string, int64), err error) {
fc() if elapsed := time.Now().Sub(begin); err != nil || elapsed > l.SlowThreshold {
sql, rows := fc()
l.Printf(l.traceErrPrefix, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
} else if l.LogLevel >= Info {
sql, rows := fc()
l.Printf(l.tracePrefix, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
} }
} }

View File

@ -2,6 +2,7 @@ package tests
import ( import (
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/logger"
"github.com/jinzhu/gorm/schema" "github.com/jinzhu/gorm/schema"
) )
@ -24,6 +25,10 @@ func (DummyDialector) QuoteChars() [2]byte {
return [2]byte{'`', '`'} // `name` return [2]byte{'`', '`'} // `name`
} }
func (DummyDialector) Explain(sql string, vars ...interface{}) string {
return logger.ExplainSQL(sql, nil, `"`, vars...)
}
func (DummyDialector) DataTypeOf(*schema.Field) string { func (DummyDialector) DataTypeOf(*schema.Field) string {
return "" return ""
} }

View File

@ -6,8 +6,8 @@ import (
"runtime" "runtime"
) )
var goSrcRegexp = regexp.MustCompile(`jinzhu/gorm/.*.go`) var goSrcRegexp = regexp.MustCompile(`/gorm/.*.go`)
var goTestRegexp = regexp.MustCompile(`jinzhu/gorm/.*test.go`) var goTestRegexp = regexp.MustCompile(`/gorm/.*test.go`)
func FileWithLineNum() string { func FileWithLineNum() string {
for i := 2; i < 15; i++ { for i := 2; i < 15; i++ {