From 1dac8593aeaf5131e148bc179a83bb3b144665a4 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Fri, 19 Dec 2025 18:06:32 +0800 Subject: [PATCH] feat: Add database transaction monitoring logs (#11406) --- agent/utils/common/sqlite.go | 4 ++ agent/utils/common/sqlite_tx_logs.go | 67 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 agent/utils/common/sqlite_tx_logs.go diff --git a/agent/utils/common/sqlite.go b/agent/utils/common/sqlite.go index 22eb8ec45..18a8bf7a3 100644 --- a/agent/utils/common/sqlite.go +++ b/agent/utils/common/sqlite.go @@ -5,6 +5,7 @@ import ( "log" "os" "path" + "strings" "time" "github.com/1Panel-dev/1Panel/agent/global" @@ -67,6 +68,9 @@ func GetDBWithPath(dbPath string) (*gorm.DB, error) { if err != nil { return nil, err } + if strings.HasSuffix(dbPath, "core.db") || strings.HasSuffix(dbPath, "agent.db") { + initializeTxWatch(db) + } sqlDB, dbError := db.DB() if dbError != nil { return nil, dbError diff --git a/agent/utils/common/sqlite_tx_logs.go b/agent/utils/common/sqlite_tx_logs.go new file mode 100644 index 000000000..6482a1754 --- /dev/null +++ b/agent/utils/common/sqlite_tx_logs.go @@ -0,0 +1,67 @@ +package common + +import ( + "context" + "fmt" + "runtime" + "strings" + "time" + + "github.com/1Panel-dev/1Panel/agent/global" + "gorm.io/gorm" +) + +type contextKey string + +func initializeTxWatch(db *gorm.DB) { + _ = db.Callback().Create().Before("gorm:begin_transaction").Register( + "my_plugin:before_begin", + func(db *gorm.DB) { + var caller []string + for i := 0; ; i++ { + pc, file, line, ok := runtime.Caller(i) + if !ok { + break + } + funcName := runtime.FuncForPC(pc).Name() + if !strings.HasPrefix(funcName, "github.com/1Panel-dev/1Panel") { + continue + } + fileParts := strings.Split(file, "/") + fileName := fileParts[len(fileParts)-1] + caller = append(caller, fmt.Sprintf("%s/%s:%d", funcName, fileName, line)) + } + txID := generateTransactionID() + db.Statement.Context = context.WithValue( + db.Statement.Context, + contextKey("tx_id"), txID, + ) + db.Statement.Context = context.WithValue( + db.Statement.Context, + contextKey("tx_start"), time.Now(), + ) + global.LOG.Debugf("[%s] tx start \n%s", txID, strings.Join(caller, "\n")) + }, + ) + + _ = db.Callback().Create().After("gorm:commit_or_rollback_transaction").Register( + "my_plugin:after_commit_or_rollback", + func(db *gorm.DB) { + ctx := db.Statement.Context + txID, _ := ctx.Value(contextKey("tx_id")).(string) + startTime, _ := ctx.Value(contextKey("tx_start")).(time.Time) + if txID != "" { + duration := time.Since(startTime) + if db.Error != nil { + global.LOG.Debugf("[%s] tx rollback! time: %v, err: %v", txID, duration, db.Error) + } else { + global.LOG.Debugf("[%s] tx commit! time: %v", txID, duration) + } + } + }, + ) +} + +func generateTransactionID() string { + return fmt.Sprintf("tx_%d", time.Now().UnixNano()) +}