初始化v1
This commit is contained in:
33
utility/database/check.go
Normal file
33
utility/database/check.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// CheckConnection 检查数据库连接
|
||||
func CheckConnection(ctx context.Context) error {
|
||||
return g.DB().PingMaster()
|
||||
}
|
||||
|
||||
// CheckConnectionMiddleware 数据库连接检查中间件
|
||||
func CheckConnectionMiddleware(r *ghttp.Request) {
|
||||
if err := CheckConnection(r.Context()); err != nil {
|
||||
g.Log().Error(r.Context(), "数据库连接失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "数据库服务暂时不可用,请稍后重试")
|
||||
return
|
||||
}
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// WithDBCheck 为控制器方法添加数据库连接检查
|
||||
func WithDBCheck(r *ghttp.Request) bool {
|
||||
if err := CheckConnection(r.Context()); err != nil {
|
||||
g.Log().Error(r.Context(), "数据库连接失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "数据库服务暂时不可用,请稍后重试")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
177
utility/database/hook.go
Normal file
177
utility/database/hook.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"nl-video-api/utility/logger"
|
||||
)
|
||||
|
||||
// SQLHook SQL执行钩子,用于记录SQL日志和错误
|
||||
type SQLHook struct{}
|
||||
|
||||
// BeforeQuery 查询前钩子
|
||||
func (h *SQLHook) BeforeQuery(ctx context.Context, link gdb.Link, sql string, args []interface{}) (context.Context, error) {
|
||||
// 记录查询开始时间
|
||||
ctx = context.WithValue(ctx, "sql_start_time", time.Now())
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterQuery 查询后钩子
|
||||
func (h *SQLHook) AfterQuery(ctx context.Context, link gdb.Link, sql string, args []interface{}, result gdb.Result, err error) error {
|
||||
// 计算执行时间
|
||||
startTime, ok := ctx.Value("sql_start_time").(time.Time)
|
||||
var duration time.Duration
|
||||
if ok {
|
||||
duration = time.Since(startTime)
|
||||
}
|
||||
|
||||
// 获取影响行数
|
||||
var rowsAffected int64
|
||||
if result != nil {
|
||||
rowsAffected = int64(result.Len())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// 记录SQL执行错误
|
||||
logger.LogDatabaseError(ctx, "Query", sql, err)
|
||||
logger.LogError(ctx, "SQL查询失败 | SQL: %s | Args: %v | Duration: %v | Error: %v",
|
||||
sql, args, duration, err)
|
||||
} else {
|
||||
// 记录SQL执行成功
|
||||
logger.LogDatabaseQuery(ctx, sql, args, duration, rowsAffected)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforeExec 执行前钩子
|
||||
func (h *SQLHook) BeforeExec(ctx context.Context, link gdb.Link, sql string, args []interface{}) (context.Context, error) {
|
||||
// 记录执行开始时间
|
||||
ctx = context.WithValue(ctx, "sql_start_time", time.Now())
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterExec 执行后钩子
|
||||
func (h *SQLHook) AfterExec(ctx context.Context, link gdb.Link, sql string, args []interface{}, result driver.Result, err error) error {
|
||||
// 计算执行时间
|
||||
startTime, ok := ctx.Value("sql_start_time").(time.Time)
|
||||
var duration time.Duration
|
||||
if ok {
|
||||
duration = time.Since(startTime)
|
||||
}
|
||||
|
||||
// 获取影响行数
|
||||
var rowsAffected int64
|
||||
if result != nil {
|
||||
if affected, e := result.RowsAffected(); e == nil {
|
||||
rowsAffected = affected
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// 记录SQL执行错误
|
||||
logger.LogDatabaseError(ctx, "Exec", sql, err)
|
||||
logger.LogError(ctx, "SQL执行失败 | SQL: %s | Args: %v | Duration: %v | Error: %v",
|
||||
sql, args, duration, err)
|
||||
} else {
|
||||
// 记录SQL执行成功
|
||||
logger.LogDatabaseQuery(ctx, sql, args, duration, rowsAffected)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforePrepare 预处理前钩子
|
||||
func (h *SQLHook) BeforePrepare(ctx context.Context, link gdb.Link, sql string) (context.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterPrepare 预处理后钩子
|
||||
func (h *SQLHook) AfterPrepare(ctx context.Context, link gdb.Link, sql string, stmt *gdb.Stmt, err error) error {
|
||||
if err != nil {
|
||||
logger.LogDatabaseError(ctx, "Prepare", sql, err)
|
||||
logger.LogError(ctx, "SQL预处理失败 | SQL: %s | Error: %v", sql, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforeCommit 提交前钩子
|
||||
func (h *SQLHook) BeforeCommit(ctx context.Context, link gdb.Link) (context.Context, error) {
|
||||
logger.LogSQL(ctx, "事务提交开始")
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterCommit 提交后钩子
|
||||
func (h *SQLHook) AfterCommit(ctx context.Context, link gdb.Link, err error) error {
|
||||
if err != nil {
|
||||
logger.LogError(ctx, "事务提交失败 | Error: %v", err)
|
||||
} else {
|
||||
logger.LogSQL(ctx, "事务提交成功")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforeRollback 回滚前钩子
|
||||
func (h *SQLHook) BeforeRollback(ctx context.Context, link gdb.Link) (context.Context, error) {
|
||||
logger.LogSQL(ctx, "事务回滚开始")
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterRollback 回滚后钩子
|
||||
func (h *SQLHook) AfterRollback(ctx context.Context, link gdb.Link, err error) error {
|
||||
if err != nil {
|
||||
logger.LogError(ctx, "事务回滚失败 | Error: %v", err)
|
||||
} else {
|
||||
logger.LogSQL(ctx, "事务回滚成功")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// InitDatabaseHook 初始化数据库钩子
|
||||
func InitDatabaseHook() {
|
||||
// 获取默认数据库实例
|
||||
db := g.DB()
|
||||
|
||||
// 添加SQL执行钩子
|
||||
db.AddHook(&SQLHook{})
|
||||
|
||||
logger.LogInfo(context.Background(), "数据库钩子初始化完成")
|
||||
}
|
||||
|
||||
// LogDatabaseConnection 记录数据库连接日志
|
||||
func LogDatabaseConnection(ctx context.Context, config gdb.ConfigNode, err error) {
|
||||
if err != nil {
|
||||
logger.LogError(ctx, "数据库连接失败 | Host: %s | Database: %s | Error: %v",
|
||||
config.Host, config.Name, err)
|
||||
} else {
|
||||
logger.LogInfo(ctx, "数据库连接成功 | Host: %s | Database: %s",
|
||||
config.Host, config.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// LogDatabasePing 记录数据库ping日志
|
||||
func LogDatabasePing(ctx context.Context, duration time.Duration, err error) {
|
||||
if err != nil {
|
||||
logger.LogError(ctx, "数据库ping失败 | Duration: %v | Error: %v", duration, err)
|
||||
} else {
|
||||
logger.LogInfo(ctx, "数据库ping成功 | Duration: %v", duration)
|
||||
}
|
||||
}
|
||||
|
||||
// LogTransactionStart 记录事务开始日志
|
||||
func LogTransactionStart(ctx context.Context, txId string) {
|
||||
logger.LogSQL(ctx, "事务开始 | TxID: %s", txId)
|
||||
}
|
||||
|
||||
// LogTransactionEnd 记录事务结束日志
|
||||
func LogTransactionEnd(ctx context.Context, txId string, success bool, duration time.Duration) {
|
||||
if success {
|
||||
logger.LogSQL(ctx, "事务结束(成功) | TxID: %s | Duration: %v", txId, duration)
|
||||
} else {
|
||||
logger.LogError(ctx, "事务结束(失败) | TxID: %s | Duration: %v", txId, duration)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user