refactor(logging): 迁移日志记录到 Zerolog 并优化错误处理

- 将日志记录库从 Logrus 替换为 Zerolog,提升性能和灵活性
- 更新各个模块的日志记录方式,确保一致性
- 优化错误处理逻辑,确保在发生错误时能够正确记录并传递错误信息
- 移除不再使用的错误处理字段,简化代码结构
- 更新相关文档以反映新的日志记录和错误处理机制
This commit is contained in:
2026-04-13 00:38:50 +08:00
parent 86daa3153e
commit 9a9b9c83ff
445 changed files with 59349 additions and 13297 deletions
+65 -73
View File
@@ -28,55 +28,37 @@ func (that *HoTimeDB) Query(query string, args ...interface{}) []Map {
// queryWithRetry 内部查询方法,支持重试标记
func (that *HoTimeDB) queryWithRetry(query string, retried bool, args ...interface{}) []Map {
// 预处理数组占位符 ?[]
query, args = that.expandArrayPlaceholder(query, args)
// 保存调试信息(加锁保护)
that.mu.Lock()
that.LastQuery = query
that.LastData = args
that.mu.Unlock()
var sqlErr error
defer func() {
if that.Mode != 0 {
that.mu.RLock()
msg := fmt.Sprintf("SQL:%s DATA:%v ERROR:%v", that.LastQuery, that.LastData, that.LastErr.GetError())
that.mu.RUnlock()
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else {
that.Log.Info(msg)
}
that.testLogBufMu.Unlock()
}
e := &DBError{Query: query, Data: args}
e.SetError(sqlErr)
that.lastError.Store(e)
that.logSQL(query, args, sqlErr)
}()
var err error
var resl *sql.Rows
// 主从数据库切换,只有select语句有从数据库
db := that.DB
if that.SlaveDB != nil {
db = that.SlaveDB
}
if db == nil {
err = errors.New("没有初始化数据库")
that.LastErr.SetError(err)
sqlErr = errors.New("没有初始化数据库")
return nil
}
// 处理参数中的 slice 类型
processedArgs := that.processArgs(args)
if that.testTx != nil {
if that.testMu != nil {
that.testMu.Lock()
}
resl, err = that.testTx.Query(query, processedArgs...)
that.LastErr.SetError(err)
if err != nil {
resl, sqlErr = that.testTx.Query(query, processedArgs...)
if sqlErr != nil {
if that.txFailed != nil {
*that.txFailed = true
}
@@ -91,13 +73,12 @@ func (that *HoTimeDB) queryWithRetry(query string, retried bool, args ...interfa
}
return result
} else if that.Tx != nil {
resl, err = that.Tx.Query(query, processedArgs...)
resl, sqlErr = that.Tx.Query(query, processedArgs...)
} else {
resl, err = db.Query(query, processedArgs...)
resl, sqlErr = db.Query(query, processedArgs...)
}
that.LastErr.SetError(err)
if err != nil {
if sqlErr != nil {
if that.Tx != nil {
if that.txFailed != nil {
*that.txFailed = true
@@ -105,6 +86,7 @@ func (that *HoTimeDB) queryWithRetry(query string, retried bool, args ...interfa
}
if !retried && that.Tx == nil {
if pingErr := db.Ping(); pingErr == nil {
sqlErr = nil // 重置,让 retry 的 defer 覆盖
return that.queryWithRetry(query, true, args...)
}
}
@@ -115,88 +97,94 @@ func (that *HoTimeDB) queryWithRetry(query string, retried bool, args ...interfa
}
// Exec 执行非查询 SQL
func (that *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, *Error) {
func (that *HoTimeDB) Exec(query string, args ...interface{}) (sql.Result, error) {
return that.execWithRetry(query, false, args...)
}
// execWithRetry 内部执行方法,支持重试标记
func (that *HoTimeDB) execWithRetry(query string, retried bool, args ...interface{}) (sql.Result, *Error) {
// 预处理数组占位符 ?[]
func (that *HoTimeDB) execWithRetry(query string, retried bool, args ...interface{}) (sql.Result, error) {
query, args = that.expandArrayPlaceholder(query, args)
// 保存调试信息(加锁保护)
that.mu.Lock()
that.LastQuery = query
that.LastData = args
that.mu.Unlock()
defer func() {
if that.Mode != 0 {
that.mu.RLock()
msg := fmt.Sprintf("SQL:%s DATA:%v ERROR:%v", that.LastQuery, that.LastData, that.LastErr.GetError())
that.mu.RUnlock()
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else {
that.Log.Info(msg)
}
that.testLogBufMu.Unlock()
}
}()
var e error
var sqlErr error
var resl sql.Result
defer func() {
e := &DBError{Query: query, Data: args}
e.SetError(sqlErr)
that.lastError.Store(e)
that.logSQL(query, args, sqlErr)
}()
if that.DB == nil {
err := errors.New("没有初始化数据库")
that.LastErr.SetError(err)
return nil, that.LastErr
sqlErr = errors.New("没有初始化数据库")
return nil, sqlErr
}
// 处理参数中的 slice 类型
processedArgs := that.processArgs(args)
if that.testTx != nil {
if that.testMu != nil {
that.testMu.Lock()
}
resl, e = that.testTx.Exec(query, processedArgs...)
resl, sqlErr = that.testTx.Exec(query, processedArgs...)
if that.testMu != nil {
that.testMu.Unlock()
}
} else if that.Tx != nil {
resl, e = that.Tx.Exec(query, processedArgs...)
resl, sqlErr = that.Tx.Exec(query, processedArgs...)
} else {
resl, e = that.DB.Exec(query, processedArgs...)
resl, sqlErr = that.DB.Exec(query, processedArgs...)
}
that.LastErr.SetError(e)
if e != nil {
// testTx 模式下不走连接池重试,避免 busy buffer
if sqlErr != nil {
if that.testTx != nil {
if that.txFailed != nil {
*that.txFailed = true
}
return resl, that.LastErr
return resl, sqlErr
}
// 事务内不做连接级重试:死锁等错误会导致 MySQL 自动回滚事务,
// 在已回滚的 Tx 上重试会以 auto-commit 模式执行,造成数据不一致
if that.Tx != nil {
if that.txFailed != nil {
*that.txFailed = true
}
return resl, that.LastErr
return resl, sqlErr
}
if !retried {
if pingErr := that.DB.Ping(); pingErr == nil {
sqlErr = nil
return that.execWithRetry(query, true, args...)
}
}
return resl, that.LastErr
return resl, sqlErr
}
return resl, that.LastErr
return resl, sqlErr
}
// logSQL 统一 SQL 日志输出(仅此一处打印,消除重复)
func (that *HoTimeDB) logSQL(query string, args []interface{}, err error) {
if err != nil {
msg := fmt.Sprintf("SQL: %s DATA: %v ERROR: %v", query, args, err)
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else if that.Log != nil {
that.Log.Error().Msg(msg)
}
that.testLogBufMu.Unlock()
return
}
// 无错误时只在 logLevel > 0 时打印 DEBUG 级别
if that.Log != nil && that.Log.GetLevel() > 0 {
msg := fmt.Sprintf("SQL: %s DATA: %v", query, args)
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else {
that.Log.Debug().Msg(msg)
}
that.testLogBufMu.Unlock()
}
}
// processArgs 处理参数中的 slice 类型
@@ -587,7 +575,9 @@ func (that *HoTimeDB) Row(resl *sql.Rows) []Map {
b[j] = &a[j]
}
if err := resl.Scan(b...); err != nil {
that.LastErr.SetError(err)
dbErr := &DBError{}
dbErr.SetError(err)
that.lastError.Store(dbErr)
return nil
}
for j := 0; j < colCount; j++ {
@@ -615,7 +605,9 @@ func (that *HoTimeDB) Row(resl *sql.Rows) []Map {
dest = append(dest, lis)
}
if err := resl.Err(); err != nil {
that.LastErr.SetError(err)
dbErr := &DBError{}
dbErr.SetError(err)
that.lastError.Store(dbErr)
}
return dest
}