mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 08:31:55 +08:00
feat(metrics): implement database initialization and cleanup for metrics tracking
- Added initTables function to create necessary tables for metrics history, status statistics, and path statistics in the database. - Implemented indexing on timestamp columns to enhance query performance. - Introduced a cleanupRoutine function to periodically delete old metrics data based on retention policies, improving database management. - Integrated logging for cleanup operations to monitor success and errors during the cleanup process.
This commit is contained in:
parent
b69a78eae0
commit
837820639f
@ -2,6 +2,8 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
"proxy-go/internal/constants"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -50,9 +52,121 @@ func NewMetricsDB(dbPath string) (*MetricsDB, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建必要的表
|
||||||
|
if err := initTables(db); err != nil {
|
||||||
|
db.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &MetricsDB{DB: db}, nil
|
return &MetricsDB{DB: db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initTables(db *sql.DB) error {
|
||||||
|
// 创建指标历史表
|
||||||
|
_, err := db.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS metrics_history (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
total_requests INTEGER,
|
||||||
|
total_errors INTEGER,
|
||||||
|
total_bytes INTEGER,
|
||||||
|
avg_latency INTEGER,
|
||||||
|
error_rate REAL
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建状态码统计表
|
||||||
|
_, err = db.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS status_stats (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
status_group TEXT,
|
||||||
|
count INTEGER
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建路径统计表
|
||||||
|
_, err = db.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS path_stats (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
path TEXT,
|
||||||
|
requests INTEGER,
|
||||||
|
errors INTEGER,
|
||||||
|
bytes INTEGER,
|
||||||
|
avg_latency INTEGER
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加索引以提高查询性能
|
||||||
|
_, err = db.Exec(`
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics_history(timestamp);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_status_timestamp ON status_stats(timestamp);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_path_timestamp ON path_stats(timestamp);
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动定期清理任务
|
||||||
|
go cleanupRoutine(db)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定期清理旧数据
|
||||||
|
func cleanupRoutine(db *sql.DB) {
|
||||||
|
ticker := time.NewTicker(constants.CleanupInterval)
|
||||||
|
for range ticker.C {
|
||||||
|
// 开始事务
|
||||||
|
tx, err := db.Begin()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error starting cleanup transaction: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除超过保留期限的数据
|
||||||
|
cutoff := time.Now().Add(-constants.DataRetention)
|
||||||
|
_, err = tx.Exec(`DELETE FROM metrics_history WHERE timestamp < ?`, cutoff)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
log.Printf("Error cleaning metrics_history: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.Exec(`DELETE FROM status_stats WHERE timestamp < ?`, cutoff)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
log.Printf("Error cleaning status_stats: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.Exec(`DELETE FROM path_stats WHERE timestamp < ?`, cutoff)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
log.Printf("Error cleaning path_stats: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交事务
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
log.Printf("Error committing cleanup transaction: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("Successfully cleaned up old metrics data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (db *MetricsDB) SaveMetrics(stats map[string]interface{}) error {
|
func (db *MetricsDB) SaveMetrics(stats map[string]interface{}) error {
|
||||||
tx, err := db.DB.Begin()
|
tx, err := db.DB.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user