gitee.com/h79/goutils@v1.22.10/dao/db/logger.go (about) 1 package db 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "gitee.com/h79/goutils/common/logger" 9 "gitee.com/h79/goutils/common/result" 10 "gitee.com/h79/goutils/dao/config" 11 "gitee.com/h79/goutils/dao/util" 12 "go.uber.org/zap" 13 "gorm.io/gorm" 14 gormLogger "gorm.io/gorm/logger" 15 "strconv" 16 "strings" 17 "time" 18 ) 19 20 type Logger struct { 21 config.SqlLogger 22 } 23 24 // LogMode log mode 25 func (l *Logger) LogMode(level gormLogger.LogLevel) gormLogger.Interface { 26 newLogger := *l 27 newLogger.LogLevel = int(level) 28 return &newLogger 29 } 30 31 // Info print info 32 func (l *Logger) Info(ctx context.Context, msg string, data ...interface{}) { 33 if l.check(gormLogger.Info) { 34 logger.Info(msg, data...) 35 } 36 } 37 38 // Warn print warn messages 39 func (l *Logger) Warn(ctx context.Context, msg string, data ...interface{}) { 40 if l.check(gormLogger.Warn) { 41 logger.Warn(msg, data...) 42 } 43 } 44 45 // Error print error messages 46 func (l *Logger) Error(ctx context.Context, msg string, data ...interface{}) { 47 if l.check(gormLogger.Error) { 48 logger.Error(msg, data...) 49 } 50 } 51 52 // Trace print sql message 53 func (l *Logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { 54 55 elapsed := time.Now().Sub(begin) 56 switch { 57 case err != nil: 58 59 recordNotFound := errors.Is(err, gorm.ErrRecordNotFound) 60 logEnabled := l.check(gormLogger.Error) && (!recordNotFound || !l.IgnoreRecordNotFoundError) 61 if !logEnabled && !l.AlarmEnabled { 62 return 63 } 64 65 sql, rows := fc() 66 if logEnabled { 67 zap.L().Info("DB", 68 zap.Error(err), 69 zap.Int64("rows", rows), 70 zap.String("sql", sql), 71 zap.String("speed", elapsed.String())) 72 } 73 74 if l.AlarmEnabled && !recordNotFound { 75 var b = strings.Builder{} 76 b.WriteString("sql: '") 77 b.WriteString(sql) 78 b.WriteString("',rows: '") 79 b.WriteString(strconv.Itoa(int(rows))) 80 b.WriteString("',speed: '") 81 b.WriteString(elapsed.String()) 82 b.WriteString("'") 83 util.Alarm(result.ErrDbInternal, "Sql", b.String(), err) 84 } 85 86 case elapsed > l.SlowThreshold && l.SlowThreshold != 0: 87 88 if !l.check(gormLogger.Warn) && !l.AlarmEnabled { 89 return 90 } 91 sql, rows := fc() 92 if l.check(gormLogger.Warn) { 93 zap.L().Warn("DB", 94 zap.String("slow", fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)), 95 zap.Int64("rows", rows), 96 zap.String("sql", sql), 97 zap.String("speed", elapsed.String())) 98 } 99 100 if l.AlarmEnabled { 101 var b = strings.Builder{} 102 b.WriteString("sql: '") 103 b.WriteString(sql) 104 b.WriteString("',rows: '") 105 b.WriteString(strconv.Itoa(int(rows))) 106 b.WriteString("',speed: '") 107 b.WriteString(elapsed.String()) 108 b.WriteString("'") 109 util.Alarm(result.ErrDbInternal, "Sql", b.String(), nil) 110 } 111 112 case l.check(gormLogger.Info): 113 sql, rows := fc() 114 zap.L().Info("DB", 115 zap.Int64("rows", rows), 116 zap.String("sql", sql), 117 zap.String("speed", elapsed.String())) 118 } 119 } 120 121 func (l *Logger) check(level gormLogger.LogLevel) bool { 122 return gormLogger.LogLevel(l.LogLevel) >= level 123 } 124 125 func (l *Logger) handlerConfig(ctx context.Context, cmd int, configType, conf string) (any, error) { 126 switch cmd { 127 case 1: 128 var c = config.SqlLogger{} 129 var err = json.Unmarshal([]byte(conf), &c) 130 if err != nil { 131 return "", err 132 } 133 l.LogLevel = c.LogLevel 134 l.IgnoreRecordNotFoundError = c.IgnoreRecordNotFoundError 135 l.AlarmEnabled = c.AlarmEnabled 136 l.SlowThreshold = c.SlowThreshold 137 return "", nil 138 case 2: //获取 139 return config.SqlLogger{}, nil 140 } 141 return "", result.RErrNotSupport 142 } 143 144 type esLogger struct { 145 Level int `json:"level"` 146 LogLevel int8 `json:"logLevel"` 147 } 148 149 func (l *esLogger) Printf(format string, v ...interface{}) { 150 if l.LogLevel < int8(l.Level) { 151 return 152 } 153 switch l.LogLevel { 154 case logger.ErrorLevel: 155 logger.E("Elastic", format, v...) 156 case logger.DebugLevel: 157 logger.D("Elastic", format, v...) 158 case logger.InfoLevel: 159 logger.I("Elastic", format, v...) 160 } 161 } 162 163 func (l *esLogger) handlerConfig(ctx context.Context, cmd int, configType, conf string) (any, error) { 164 switch cmd { 165 case 1: 166 var c = esLogger{} 167 var err = json.Unmarshal([]byte(conf), &c) 168 if err != nil { 169 return "", err 170 } 171 l.Level = c.Level 172 l.LogLevel = c.LogLevel 173 return "", nil 174 case 2: //获取 175 return esLogger{}, nil 176 } 177 return "", result.RErrNotSupport 178 }