diff --git a/internal/metrics/collector.go b/internal/metrics/collector.go index e57f646..e41f17a 100644 --- a/internal/metrics/collector.go +++ b/internal/metrics/collector.go @@ -67,18 +67,13 @@ func InitCollector(dbPath string, config *config.Config) error { globalCollector.persistentStats.totalRequests.Store(lastMetrics.TotalRequests) globalCollector.persistentStats.totalErrors.Store(lastMetrics.TotalErrors) globalCollector.persistentStats.totalBytes.Store(lastMetrics.TotalBytes) - if err := loadRecentStatusStats(db); err != nil { - log.Printf("Warning: Failed to load recent status stats: %v", err) + if err := globalCollector.LoadRecentStats(); err != nil { + log.Printf("Warning: Failed to load recent stats: %v", err) } log.Printf("Loaded historical metrics: requests=%d, errors=%d, bytes=%d", lastMetrics.TotalRequests, lastMetrics.TotalErrors, lastMetrics.TotalBytes) } - // 加载最近5分钟的统计数据 - if err := globalCollector.LoadRecentStats(); err != nil { - log.Printf("Warning: Failed to load recent stats: %v", err) - } - globalCollector.cache = cache.NewCache(constants.CacheTTL) globalCollector.monitor = monitor.NewMonitor() @@ -591,30 +586,3 @@ func formatAvgLatency(latencySum, requests int64) string { } 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() -} diff --git a/internal/models/metrics.go b/internal/models/metrics.go index 6ccb8c6..1cfd7d3 100644 --- a/internal/models/metrics.go +++ b/internal/models/metrics.go @@ -7,6 +7,7 @@ import ( "log" "proxy-go/internal/constants" "strings" + "sync" "sync/atomic" "time" @@ -793,3 +794,94 @@ func (db *MetricsDB) GetStats() map[string]interface{} { "last_error": db.stats.lastError.Load(), } } + +func (db *MetricsDB) LoadRecentStats(statusStats *[6]atomic.Int64, pathStats *sync.Map, refererStats *sync.Map) error { + // 加载状态码统计 + rows, err := db.DB.Query(` + SELECT status_group, SUM(count) as count + FROM status_code_history + WHERE timestamp >= datetime('now', '-5', 'minutes') + GROUP BY status_group + `) + 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(statusStats) { + statusStats[idx].Store(count) + } + } + } + + // 加载路径统计 + rows, err = db.DB.Query(` + SELECT + path, + SUM(request_count) as requests, + SUM(error_count) as errors, + AVG(bytes_transferred) as bytes, + AVG(avg_latency) as latency + FROM popular_paths_history + WHERE timestamp >= datetime('now', '-5', 'minutes') + GROUP BY path + ORDER BY requests DESC + LIMIT 10 + `) + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + var path string + var requests, errors, bytes int64 + var latency float64 + if err := rows.Scan(&path, &requests, &errors, &bytes, &latency); err != nil { + return err + } + stats := &PathStats{} + stats.Requests.Store(requests) + stats.Errors.Store(errors) + stats.Bytes.Store(bytes) + stats.LatencySum.Store(int64(latency)) + pathStats.Store(path, stats) + } + + // 加载引用来源统计 + rows, err = db.DB.Query(` + SELECT + referer, + SUM(request_count) as requests + FROM referer_history + WHERE timestamp >= datetime('now', '-5', 'minutes') + GROUP BY referer + ORDER BY requests DESC + LIMIT 10 + `) + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + var referer string + var requests int64 + if err := rows.Scan(&referer, &requests); err != nil { + return err + } + stats := &PathStats{} + stats.Requests.Store(requests) + refererStats.Store(referer, stats) + } + + return nil +}