github.com/abolfazlbeh/zhycan@v0.0.0-20230819144214-24cf38237387/internal/db/logger.go (about) 1 package db 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 zlogger "github.com/abolfazlbeh/zhycan/internal/logger" 8 "go.mongodb.org/mongo-driver/mongo/options" 9 "gorm.io/gorm/logger" 10 "gorm.io/gorm/utils" 11 "strings" 12 "time" 13 ) 14 15 // MARK: Variables 16 var ( 17 DbLogType = zlogger.NewLogType("DB_OP") 18 DbTraceLogType = zlogger.NewLogType("DB_TRACE_OP") 19 ) 20 21 // DbLogger - DB Logger struct 22 type DbLogger struct { 23 logger.Config 24 } 25 26 // NewDbLogger - return instance of DbLogger which implement Interface 27 func NewDbLogger(config LoggerConfig) logger.Interface { 28 logLevel := logger.Silent 29 switch strings.ToLower(config.LogLevel) { 30 case "error": 31 logLevel = logger.Error 32 break 33 case "warn": 34 logLevel = logger.Warn 35 break 36 case "info": 37 logLevel = logger.Info 38 break 39 } 40 41 return &DbLogger{Config: logger.Config{ 42 SlowThreshold: time.Duration(config.SlowThreshold) * time.Millisecond, 43 Colorful: false, 44 IgnoreRecordNotFoundError: config.IgnoreRecordNotFoundError, 45 ParameterizedQueries: config.ParameterizedQueries, 46 LogLevel: logLevel, 47 }} 48 } 49 50 // LogMode - set log mode 51 func (l *DbLogger) LogMode(level logger.LogLevel) logger.Interface { 52 newlogger := *l 53 newlogger.LogLevel = level 54 return &newlogger 55 } 56 57 // Info - print info 58 func (l DbLogger) Info(ctx context.Context, msg string, data ...interface{}) { 59 ll, _ := zlogger.GetManager().GetLogger() 60 if l.LogLevel >= logger.Info && ll != nil { 61 newMsg := fmt.Sprintf(msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) 62 ll.Log(zlogger.NewLogObject( 63 zlogger.INFO, "db", DbLogType, 64 time.Now().UTC(), newMsg, nil, 65 )) 66 } 67 } 68 69 // Warn - print warn messages 70 func (l DbLogger) Warn(ctx context.Context, msg string, data ...interface{}) { 71 ll, _ := zlogger.GetManager().GetLogger() 72 if l.LogLevel >= logger.Warn && ll != nil { 73 newMsg := fmt.Sprintf(msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) 74 ll.Log(zlogger.NewLogObject( 75 zlogger.WARNING, "db", DbLogType, 76 time.Now().UTC(), newMsg, nil, 77 )) 78 } 79 } 80 81 // Error - print error messages 82 func (l DbLogger) Error(ctx context.Context, msg string, data ...interface{}) { 83 ll, _ := zlogger.GetManager().GetLogger() 84 if l.LogLevel >= logger.Error && ll != nil { 85 newMsg := fmt.Sprintf(msg, append([]interface{}{utils.FileWithLineNum()}, data...)...) 86 ll.Log(zlogger.NewLogObject( 87 zlogger.ERROR, "db", DbLogType, 88 time.Now().UTC(), newMsg, nil, 89 )) 90 } 91 } 92 93 // Trace - print sql message 94 func (l DbLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { 95 if l.LogLevel <= logger.Silent { 96 return 97 } 98 99 ll, _ := zlogger.GetManager().GetLogger() 100 if ll != nil { 101 elapsed := time.Since(begin) 102 switch { 103 case err != nil && l.LogLevel >= logger.Error && 104 (!errors.Is(err, logger.ErrRecordNotFound) || 105 !l.IgnoreRecordNotFoundError): 106 sql, rows := fc() 107 msgLiteral := "%s %s\n[%.3fms] [rows:%v] %s" 108 if rows == -1 { 109 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) 110 ll.Log(zlogger.NewLogObject( 111 zlogger.ERROR, "db", DbTraceLogType, 112 time.Now().UTC(), msg, []interface{}{err, sql}, 113 )) 114 } else { 115 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) 116 ll.Log(zlogger.NewLogObject( 117 zlogger.ERROR, "db", DbTraceLogType, 118 time.Now().UTC(), msg, []interface{}{err, sql, rows}, 119 )) 120 } 121 case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn: 122 sql, rows := fc() 123 slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold) 124 125 msgLiteral := "%s %s\n[%.3fms] [rows:%v] %s" 126 if rows == -1 { 127 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) 128 ll.Log(zlogger.NewLogObject( 129 zlogger.WARNING, "db", DbTraceLogType, 130 time.Now().UTC(), msg, []interface{}{slowLog, sql}, 131 )) 132 } else { 133 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) 134 ll.Log(zlogger.NewLogObject( 135 zlogger.WARNING, "db", DbTraceLogType, 136 time.Now().UTC(), msg, []interface{}{slowLog, sql, rows}, 137 )) 138 } 139 case l.LogLevel == logger.Info: 140 sql, rows := fc() 141 142 msgLiteral := "%s\n[%.3fms] [rows:%v] %s" 143 if rows == -1 { 144 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) 145 ll.Log(zlogger.NewLogObject( 146 zlogger.INFO, "db", DbTraceLogType, 147 time.Now().UTC(), msg, []interface{}{sql}, 148 )) 149 } else { 150 msg := fmt.Sprintf(msgLiteral, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) 151 ll.Log(zlogger.NewLogObject( 152 zlogger.INFO, "db", DbTraceLogType, 153 time.Now().UTC(), msg, []interface{}{sql, rows}, 154 )) 155 } 156 } 157 } 158 } 159 160 // MongoLogger - Mongo DB Logger struct 161 type MongoLogger struct { 162 } 163 164 func (m *MongoLogger) Info(level int, message string, keysAndValues ...interface{}) { 165 ll, _ := zlogger.GetManager().GetLogger() 166 if ll != nil { 167 if options.LogLevel(level) == options.LogLevelInfo { 168 ll.Log(zlogger.NewLogObject( 169 zlogger.INFO, "mongodb", DbLogType, 170 time.Now().UTC(), message, keysAndValues, 171 )) 172 } else if options.LogLevel(level) == options.LogLevelDebug { 173 ll.Log(zlogger.NewLogObject( 174 zlogger.DEBUG, "mongodb", DbLogType, 175 time.Now().UTC(), message, keysAndValues, 176 )) 177 } 178 } 179 } 180 181 func (m *MongoLogger) Error(err error, message string, keysAndValues ...interface{}) { 182 ll, _ := zlogger.GetManager().GetLogger() 183 if ll != nil { 184 msg := fmt.Sprintf("%s -> err: %v", message, err) 185 ll.Log(zlogger.NewLogObject( 186 zlogger.ERROR, "mongodb", DbLogType, 187 time.Now().UTC(), msg, keysAndValues, 188 )) 189 } 190 }