mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 08:31:55 +08:00
feat(metrics): add recent status stats loading and optimize database transaction settings
- Implemented a new function to load recent status statistics from the database, enhancing the collector's ability to track real-time metrics. - Added error logging for failed status stats loading to improve monitoring and debugging capabilities. - Moved database transaction optimization settings outside of the transaction scope in SaveMetrics, improving performance during metric saving operations. - Updated SQL queries in GetRecentMetrics to streamline time filtering logic, ensuring accurate retrieval of recent metrics. These changes enhance the metrics collection process and improve the overall performance and reliability of the metrics dashboard.
This commit is contained in:
parent
96a792abf2
commit
97a195c9dd
@ -66,6 +66,9 @@ func InitCollector(dbPath string, config *config.Config) error {
|
|||||||
globalCollector.persistentStats.totalRequests.Store(lastMetrics.TotalRequests)
|
globalCollector.persistentStats.totalRequests.Store(lastMetrics.TotalRequests)
|
||||||
globalCollector.persistentStats.totalErrors.Store(lastMetrics.TotalErrors)
|
globalCollector.persistentStats.totalErrors.Store(lastMetrics.TotalErrors)
|
||||||
globalCollector.persistentStats.totalBytes.Store(lastMetrics.TotalBytes)
|
globalCollector.persistentStats.totalBytes.Store(lastMetrics.TotalBytes)
|
||||||
|
if err := loadRecentStatusStats(db); err != nil {
|
||||||
|
log.Printf("Warning: Failed to load recent status stats: %v", err)
|
||||||
|
}
|
||||||
log.Printf("Loaded historical metrics: requests=%d, errors=%d, bytes=%d",
|
log.Printf("Loaded historical metrics: requests=%d, errors=%d, bytes=%d",
|
||||||
lastMetrics.TotalRequests, lastMetrics.TotalErrors, lastMetrics.TotalBytes)
|
lastMetrics.TotalRequests, lastMetrics.TotalErrors, lastMetrics.TotalBytes)
|
||||||
}
|
}
|
||||||
@ -586,3 +589,30 @@ func formatAvgLatency(latencySum, requests int64) string {
|
|||||||
}
|
}
|
||||||
return FormatDuration(time.Duration(latencySum / requests))
|
return FormatDuration(time.Duration(latencySum / requests))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadRecentStatusStats(db *models.MetricsDB) error {
|
||||||
|
rows, err := db.DB.Query(`
|
||||||
|
SELECT status_group, count
|
||||||
|
FROM status_stats
|
||||||
|
WHERE timestamp >= datetime('now', '-5', 'minutes')
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var group string
|
||||||
|
var count int64
|
||||||
|
if err := rows.Scan(&group, &count); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(group) > 0 {
|
||||||
|
idx := (int(group[0]) - '0') - 1
|
||||||
|
if idx >= 0 && idx < len(globalCollector.statusStats) {
|
||||||
|
globalCollector.statusStats[idx].Store(count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
|
@ -285,7 +285,7 @@ func cleanupRoutine(db *sql.DB) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优化清理性能
|
// 优化理性能
|
||||||
if _, err := tx.Exec("PRAGMA synchronous = NORMAL"); err != nil {
|
if _, err := tx.Exec("PRAGMA synchronous = NORMAL"); err != nil {
|
||||||
log.Printf("Error setting synchronous mode: %v", err)
|
log.Printf("Error setting synchronous mode: %v", err)
|
||||||
}
|
}
|
||||||
@ -367,20 +367,20 @@ func getDBSize(db *sql.DB) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *MetricsDB) SaveMetrics(stats map[string]interface{}) error {
|
func (db *MetricsDB) SaveMetrics(stats map[string]interface{}) error {
|
||||||
|
// 设置事务优化参数 - 移到事务外
|
||||||
|
if _, err := db.DB.Exec("PRAGMA synchronous = NORMAL"); err != nil {
|
||||||
|
return fmt.Errorf("failed to set synchronous mode: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := db.DB.Exec("PRAGMA journal_mode = WAL"); err != nil {
|
||||||
|
return fmt.Errorf("failed to set journal mode: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
tx, err := db.DB.Begin()
|
tx, err := db.DB.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
// 设置事务优化参数
|
|
||||||
if _, err := tx.Exec("PRAGMA synchronous = NORMAL"); err != nil {
|
|
||||||
return fmt.Errorf("failed to set synchronous mode: %v", err)
|
|
||||||
}
|
|
||||||
if _, err := tx.Exec("PRAGMA journal_mode = WAL"); err != nil {
|
|
||||||
return fmt.Errorf("failed to set journal mode: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用预处理语句提高性能
|
// 使用预处理语句提高性能
|
||||||
stmt, err := tx.Prepare(`
|
stmt, err := tx.Prepare(`
|
||||||
INSERT INTO metrics_history (
|
INSERT INTO metrics_history (
|
||||||
@ -464,14 +464,6 @@ func (db *MetricsDB) GetRecentMetrics(hours float64) ([]HistoricalMetrics, error
|
|||||||
return nil, fmt.Errorf("failed to commit transaction: %v", err)
|
return nil, fmt.Errorf("failed to commit transaction: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算查询时间范围
|
|
||||||
endTime := time.Now()
|
|
||||||
startTime := endTime.Add(-time.Duration(hours * float64(time.Hour.Nanoseconds())))
|
|
||||||
|
|
||||||
// 格式化时间
|
|
||||||
startTimeStr := startTime.Format("2006-01-02 15:04:05")
|
|
||||||
endTimeStr := endTime.Format("2006-01-02 15:04:05")
|
|
||||||
|
|
||||||
// 处理小于1小时的情况
|
// 处理小于1小时的情况
|
||||||
if hours <= 0 {
|
if hours <= 0 {
|
||||||
hours = 0.5 // 30分钟
|
hours = 0.5 // 30分钟
|
||||||
@ -507,11 +499,11 @@ func (db *MetricsDB) GetRecentMetrics(hours float64) ([]HistoricalMetrics, error
|
|||||||
rows, err := db.DB.Query(`
|
rows, err := db.DB.Query(`
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
time_series(time_point) AS (
|
time_series(time_point) AS (
|
||||||
SELECT datetime(?, 'localtime')
|
SELECT datetime('now', 'localtime')
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT datetime(time_point, '-' || ? || ' minutes')
|
SELECT datetime(time_point, '-' || ? || ' minutes')
|
||||||
FROM time_series
|
FROM time_series
|
||||||
WHERE time_point > datetime(?, 'localtime')
|
WHERE time_point > datetime('now', '-' || ? || ' hours', 'localtime')
|
||||||
LIMIT 1000
|
LIMIT 1000
|
||||||
),
|
),
|
||||||
grouped_metrics AS (
|
grouped_metrics AS (
|
||||||
@ -522,7 +514,7 @@ func (db *MetricsDB) GetRecentMetrics(hours float64) ([]HistoricalMetrics, error
|
|||||||
MAX(total_bytes) as period_bytes,
|
MAX(total_bytes) as period_bytes,
|
||||||
AVG(avg_latency) as avg_latency
|
AVG(avg_latency) as avg_latency
|
||||||
FROM metrics_history
|
FROM metrics_history
|
||||||
WHERE timestamp BETWEEN ? AND ?
|
WHERE timestamp >= datetime('now', '-' || ? || ' hours', 'localtime')
|
||||||
GROUP BY group_time
|
GROUP BY group_time
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
@ -535,7 +527,7 @@ func (db *MetricsDB) GetRecentMetrics(hours float64) ([]HistoricalMetrics, error
|
|||||||
LEFT JOIN grouped_metrics m ON strftime(?, ts.time_point, 'localtime') = m.group_time
|
LEFT JOIN grouped_metrics m ON strftime(?, ts.time_point, 'localtime') = m.group_time
|
||||||
ORDER BY timestamp DESC
|
ORDER BY timestamp DESC
|
||||||
LIMIT 1000
|
LIMIT 1000
|
||||||
`, endTimeStr, timeStep, startTimeStr, interval, startTimeStr, endTimeStr, interval, interval)
|
`, timeStep, hours, interval, hours, interval, interval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user