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 (
|
||||
"database/sql"
|
||||
"log"
|
||||
"proxy-go/internal/constants"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@ -50,9 +52,121 @@ func NewMetricsDB(dbPath string) (*MetricsDB, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建必要的表
|
||||
if err := initTables(db); err != nil {
|
||||
db.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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 {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user