diff --git a/go.mod b/go.mod index 566f753..f195fd4 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,8 @@ require ( github.com/natefinch/lumberjack v2.0.0+incompatible github.com/prometheus/common v0.32.0 go.uber.org/zap v1.20.0 + gorm.io/driver/mysql v1.3.2 + gorm.io/gorm v1.23.2 ) require ( @@ -16,9 +18,12 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/gogo/protobuf v1.3.1 // indirect github.com/golang/protobuf v1.4.3 // indirect github.com/golang/snappy v0.0.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.4 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.11 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect diff --git a/go.sum b/go.sum index 7e9d461..00b61c1 100644 --- a/go.sum +++ b/go.sum @@ -257,6 +257,8 @@ github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7 github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -417,6 +419,10 @@ github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bS github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -1117,6 +1123,11 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.3.2 h1:QJryWiqQ91EvZ0jZL48NOpdlPdMjdip1hQ8bTgo4H7I= +gorm.io/driver/mysql v1.3.2/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U= +gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.2 h1:xmq9QRMWL8HTJyhAUBXy8FqIIQCYESeKfJL4DoGKiWQ= +gorm.io/gorm v1.23.2/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/gorm.go b/gorm.go index 762052b..e719899 100644 --- a/gorm.go +++ b/gorm.go @@ -1,21 +1,85 @@ package logger -import "strings" +import ( + "context" + "errors" + "fmt" + gl "gorm.io/gorm/logger" + "time" +) // 基于Gorm的日志实现 -type gormLogger struct{} - -// 打印 -func (gormLogger) Write(p []byte) (n int, err error) { - str := string(p) - // 去掉第一行 - //str = strings.Split(str, "\n")[1] - str = strings.Join(strings.Split(str, "\n")[1:], " ") - Say.Debug(str) - return 0, nil +type gormLogger struct { + gl.Config } -// NewGormLogger ... -func NewGormLogger() *gormLogger { - return &gormLogger{} +// LogMode 实现LogMode接口 +func (l *gormLogger) LogMode(level gl.LogLevel) gl.Interface { + nl := *l + nl.LogLevel = level + return &nl +} + +// Info 实现Info接口 +func (l gormLogger) Info(ctx context.Context, msg string, data ...interface{}) { + if l.LogLevel >= gl.Info { + // // 去掉第一行 + // msg = strings.Join(strings.Split(msg, "\n")[1:], " ") + // Say.Info(msg) + // + // l.Printf(msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) + } +} + +// Warn 实现Warn接口 +func (l gormLogger) Warn(ctx context.Context, msg string, data ...interface{}) { + if l.LogLevel >= gl.Warn { + // + } +} + +// 实现Error接口 +func (l gormLogger) Error(ctx context.Context, msg string, data ...interface{}) { + if l.LogLevel >= gl.Error { + // + } +} + +// Trace 实现Trace接口 +func (l gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + if l.LogLevel <= gl.Silent { + return + } + + elapsed := time.Since(begin) + sql, rows := fc() + msg := fmt.Sprintf("[%v] [rows:%v] %s", elapsed.String(), rows, sql) + if rows == -1 { + msg = fmt.Sprintf("%s [-] %s", elapsed.String(), sql) + } + + switch { + case err != nil && l.LogLevel >= gl.Error && (!errors.Is(err, gl.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError): + Say.Errorf("%s -> %s", err.Error(), sql) + case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gl.Warn: + slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold) + Say.Warnf("%v -> %v", slowLog, sql) + case l.LogLevel == gl.Info: + Say.Info(msg) + } +} + +// NewGormLoggerWithConfig ... +func NewGormLoggerWithConfig(config gl.Config) gl.Interface { + return &gormLogger{config} +} + +// DefaultGormLogger 默认的日志实现 +func DefaultGormLogger() gl.Interface { + return &gormLogger{gl.Config{ + SlowThreshold: time.Second, // Slow SQL threshold + IgnoreRecordNotFoundError: false, // 忽略没找到结果的错误 + LogLevel: gl.Info, // Log level + Colorful: false, // Disable color + }} } diff --git a/gorm_test.go b/gorm_test.go new file mode 100644 index 0000000..7fdd8e2 --- /dev/null +++ b/gorm_test.go @@ -0,0 +1,22 @@ +package logger + +import ( + "gorm.io/driver/mysql" + "gorm.io/gorm" + "testing" +) + +func TestGormLogger(t *testing.T) { + dsn := "saas:saas123@tcp(10.11.0.10:3307)/saas_tenant?charset=utf8mb4&parseTime=True&loc=Local" + + engine, err := gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: DefaultGormLogger()}) + if err != nil { + Say.Panicf("mysql connect error: %s", err.Error()) + } + + var count int64 + if err := engine.Table("t_tenant1").Count(&count).Error; err != nil { + t.Log(err) + } + t.Logf("count: %d", count) +}