mirror of https://github.com/go-sonic/sonic.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.0 KiB
Go
129 lines
4.0 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
|
|
"github.com/go-sonic/sonic/config"
|
|
)
|
|
|
|
type gormLogger struct {
|
|
logger.Config
|
|
traceStr string
|
|
traceWarnStr string
|
|
traceErrStr string
|
|
zapLogger *zap.Logger
|
|
}
|
|
|
|
func NewGormLogger(conf *config.Config, zapLogger *zap.Logger) logger.Interface {
|
|
logConfig := logger.Config{
|
|
SlowThreshold: 200 * time.Millisecond,
|
|
LogLevel: GetGormLogLevel(conf.Log.Levels.Gorm),
|
|
IgnoreRecordNotFoundError: true,
|
|
Colorful: config.IsDev(),
|
|
}
|
|
gl := &gormLogger{
|
|
Config: logConfig,
|
|
traceStr: "[%.3fms] [rows:%v] %s",
|
|
traceWarnStr: "%s [%.3fms] [rows:%v] %s",
|
|
traceErrStr: "%s [%.3fms] [rows:%v] %s",
|
|
zapLogger: zapLogger,
|
|
}
|
|
if logConfig.Colorful {
|
|
gl.traceStr = logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
|
|
gl.traceWarnStr = "%s " + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset
|
|
gl.traceErrStr = logger.MagentaBold + "%s " + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
|
|
}
|
|
return gl
|
|
}
|
|
|
|
func (l *gormLogger) LogMode(level logger.LogLevel) logger.Interface {
|
|
newLogger := *l
|
|
newLogger.LogLevel = level
|
|
return &newLogger
|
|
}
|
|
|
|
const level = 2
|
|
|
|
func (l *gormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Infof(msg, data...)
|
|
}
|
|
|
|
func (l *gormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Warnf(msg, data...)
|
|
}
|
|
|
|
func (l *gormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Errorf(msg, data...)
|
|
}
|
|
|
|
func (l *gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
|
if l.LogLevel <= logger.Silent {
|
|
return
|
|
}
|
|
|
|
elapsed := time.Since(begin)
|
|
switch {
|
|
case err != nil && l.LogLevel >= logger.Error && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError):
|
|
sql, rows := fc()
|
|
if rows == -1 {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Errorf(l.traceErrStr, err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
|
|
} else {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Errorf(l.traceErrStr, err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
|
|
}
|
|
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
|
|
sql, rows := fc()
|
|
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)
|
|
if rows == -1 {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Warnf(l.traceWarnStr, slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
|
|
} else {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Warnf(l.traceWarnStr, slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
|
|
}
|
|
case l.LogLevel == logger.Info:
|
|
sql, rows := fc()
|
|
if rows == -1 {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Infof(l.traceStr, float64(elapsed.Nanoseconds())/1e6, "-", sql)
|
|
} else {
|
|
l.zapLogger.WithOptions(zap.AddCallerSkip(getCallerSkip()-level)).Sugar().Infof(l.traceStr, float64(elapsed.Nanoseconds())/1e6, rows, sql)
|
|
}
|
|
}
|
|
}
|
|
|
|
func getCallerSkip() int {
|
|
for i := 3; i < 15; i++ {
|
|
pc := make([]uintptr, 1)
|
|
numFrames := runtime.Callers(i, pc)
|
|
if numFrames < 1 {
|
|
return i
|
|
}
|
|
frame, _ := runtime.CallersFrames(pc).Next()
|
|
if !strings.Contains(frame.Function, "gorm.io") && !strings.Contains(frame.Function, "github.com/go-sonic/sonic/dal") {
|
|
return i
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func GetGormLogLevel(level string) logger.LogLevel {
|
|
switch level {
|
|
case "info":
|
|
return logger.Info
|
|
case "warn":
|
|
return logger.Warn
|
|
case "error":
|
|
return logger.Error
|
|
case "silent":
|
|
return logger.Silent
|
|
default:
|
|
panic("log level error")
|
|
}
|
|
}
|