Skip to content

Commit

Permalink
Add gorm日志组件;
Browse files Browse the repository at this point in the history
  • Loading branch information
ZYallers committed Jun 30, 2022
1 parent d34c0d7 commit a9451b2
Show file tree
Hide file tree
Showing 9 changed files with 405 additions and 253 deletions.
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ module github.com/ZYallers/golib
go 1.15

require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/BurntSushi/toml v1.1.0 // indirect
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/go-redis/redis v6.15.9+incompatible
github.com/json-iterator/go v1.1.12
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.18.1 // indirect
github.com/onsi/gomega v1.19.0 // indirect
github.com/spf13/cast v1.5.0
github.com/syyongx/php2go v0.9.6
github.com/techoner/gophp v0.2.0
github.com/tidwall/gjson v1.6.1
Expand Down
128 changes: 128 additions & 0 deletions utils/logger/gorm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package logger

import (
"context"
"fmt"
"github.com/spf13/cast"
"go.uber.org/zap"
gormLogger "gorm.io/gorm/logger"
"regexp"
"runtime"
"strings"
"time"
)

const (
regular = "/(service|model|logic)/"
infoStr = "%s\n[info] "
warnStr = "%s\n[warn] "
errStr = "%s\n[error] "
traceStr = "%s\n[runtime:%.3fms] [rows:%v]\n%s"
traceWarnStr = "%s\n%s\n[runtime:%.3fms] [rows:%v]\n%s"
traceErrStr = "%s\n%s\n[runtime:%.3fms] [rows:%v]\n%s"
)

type GormLogSender interface {
PushMessage(string)
}

type logger struct {
GormLogSender
gormLogger.Config
Writer *zap.Logger
infoStr, warnStr, errStr, traceStr, traceErrStr, traceWarnStr string
}

func NewGormLogger(name string, slowThreshold time.Duration, level gormLogger.LogLevel, sender GormLogSender) gormLogger.Interface {
return &logger{
GormLogSender: sender,
Writer: Use(name),
Config: gormLogger.Config{SlowThreshold: slowThreshold, LogLevel: level, Colorful: false},
infoStr: infoStr,
warnStr: warnStr,
errStr: errStr,
traceStr: traceStr,
traceWarnStr: traceWarnStr,
traceErrStr: traceErrStr,
}
}

func (l *logger) LogMode(level gormLogger.LogLevel) gormLogger.Interface {
newLogger := *l
newLogger.LogLevel = level
return &newLogger
}

func (l logger) Printf(level gormLogger.LogLevel, format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
switch level {
case gormLogger.Error:
l.Writer.Error(s)
l.PushMessage(s)
case gormLogger.Warn:
l.Writer.Warn(s)
l.PushMessage(s)
case gormLogger.Info:
l.Writer.Info(s)
default:
l.Writer.Debug(s)
}
}

func (l logger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormLogger.Info {
l.Printf(gormLogger.Info, l.infoStr+msg, append([]interface{}{fileWithLine()}, data...)...)
}
}

func (l logger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormLogger.Warn {
l.Printf(gormLogger.Warn, l.warnStr+msg, append([]interface{}{fileWithLine()}, data...)...)
}
}

func (l logger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormLogger.Error {
l.Printf(gormLogger.Error, l.errStr+msg, append([]interface{}{fileWithLine()}, data...)...)
}
}

func (l logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel > 0 {
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= gormLogger.Error:
sql, rows := fc()
if rows == -1 {
l.Printf(gormLogger.Error, l.traceErrStr, fileWithLine(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
l.Printf(gormLogger.Error, l.traceErrStr, fileWithLine(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gormLogger.Warn:
sql, rows := fc()
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)
if rows == -1 {
l.Printf(gormLogger.Warn, l.traceWarnStr, slowLog, fileWithLine(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
l.Printf(gormLogger.Warn, l.traceWarnStr, slowLog, fileWithLine(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case l.LogLevel >= gormLogger.Info:
sql, rows := fc()
if rows == -1 {
l.Printf(gormLogger.Info, l.traceStr, fileWithLine(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
l.Printf(gormLogger.Info, l.traceStr, fileWithLine(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
}
}
}

func fileWithLine() string {
for i := 2; i < 15; i++ {
_, file, line, ok := runtime.Caller(i)
if ok && strings.HasSuffix(file, ".go") && regexp.MustCompile(regular).MatchString(file) {
return file + ":" + cast.ToString(line)
}
}
return ""
}
47 changes: 47 additions & 0 deletions utils/mysql/dialect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package mysql

import (
"fmt"
"github.com/ZYallers/golib/types"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)

const (
defaultCharset = "utf8mb4"
defaultLoc = "Local"
defaultParseTime = "true"
defaultMaxAllowedPacket = "0"
defaultTimeout = "15s"
)

func (m *Model) Dialector(dialect *types.MysqlDialect) gorm.Dialector {
return mysql.Open(m.ParseDSN(dialect))
}

func (m *Model) ParseDSN(dialect *types.MysqlDialect) string {
charset := defaultCharset
if dialect.Charset != "" {
charset = dialect.Charset
}
parseTime := defaultParseTime
if dialect.ParseTime != "" {
parseTime = dialect.ParseTime
}
loc := defaultLoc
if dialect.Loc != "" {
loc = dialect.Loc
}
maxAllowedPacket := defaultMaxAllowedPacket
if dialect.MaxAllowedPacket != "" {
maxAllowedPacket = dialect.MaxAllowedPacket
}
timeout := defaultTimeout
if dialect.Timeout != "" {
timeout = dialect.Timeout
}
dns := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%s&loc=%s&maxAllowedPacket=%s&timeout=%s",
dialect.User, dialect.Pwd, dialect.Host, dialect.Port, dialect.Db,
charset, parseTime, loc, maxAllowedPacket, timeout)
return dns
}
43 changes: 43 additions & 0 deletions utils/mysql/execute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package mysql

import (
"errors"
"strings"
)

func (m *Model) Save(value interface{}, updates ...interface{}) (interface{}, error) {
db := m.DB().Table(m.Table)
if ul := len(updates); ul > 0 {
if i, ok := updates[0].(int); ok && i > 0 {
if ul > 1 {
if s, ok := updates[1].(string); ok && s != "" {
db = db.Select(strings.Split(s, ","))
}
}
return value, db.Updates(value).Error
}
}
return value, db.Create(value).Error
}

func (m *Model) SaveOrUpdate(value interface{}, primaryKey int, updateFields string) (interface{}, error) {
db := m.DB().Table(m.Table)
if primaryKey > 0 {
if updateFields != "" {
db = db.Select(strings.Split(updateFields, ","))
}
return value, db.Updates(value).Error
}
return value, db.Create(value).Error
}

func (m *Model) Update(where []interface{}, value interface{}) error {
return m.DB().Table(m.Table).Where(where[0], where[1:]...).Updates(value).Error
}

func (m *Model) Delete(where []interface{}) error {
if where == nil {
return errors.New("query condition cannot be empty")
}
return m.DB().Table(m.Table).Where(where[0], where[1:]...).Delete(nil).Error
}
Loading

0 comments on commit a9451b2

Please sign in to comment.