移除对基本指标的持久化和加载,简化指标存储逻辑,仅保留状态码和引用来源统计的持久化。仪表板页面状态码统计标题中添加总请求数信息,提升用户体验。

This commit is contained in:
wood chen 2025-07-11 19:55:05 +08:00
parent febe460baa
commit cc677bcf72
2 changed files with 11 additions and 44 deletions

View File

@ -23,7 +23,6 @@ type MetricsStorage struct {
wg sync.WaitGroup wg sync.WaitGroup
lastSaveTime time.Time lastSaveTime time.Time
mutex sync.RWMutex mutex sync.RWMutex
metricsFile string
statusCodeFile string statusCodeFile string
refererStatsFile string refererStatsFile string
} }
@ -39,7 +38,6 @@ func NewMetricsStorage(collector *Collector, dataDir string, saveInterval time.D
saveInterval: saveInterval, saveInterval: saveInterval,
dataDir: dataDir, dataDir: dataDir,
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
metricsFile: filepath.Join(dataDir, "metrics.json"),
statusCodeFile: filepath.Join(dataDir, "status_codes.json"), statusCodeFile: filepath.Join(dataDir, "status_codes.json"),
refererStatsFile: filepath.Join(dataDir, "referer_stats.json"), refererStatsFile: filepath.Join(dataDir, "referer_stats.json"),
} }
@ -104,23 +102,8 @@ func (ms *MetricsStorage) SaveMetrics() error {
// 获取当前指标数据 // 获取当前指标数据
stats := ms.collector.GetStats() stats := ms.collector.GetStats()
// 保存基本指标 - 只保存必要的字段 // 不再持久化 basicMetricsmetrics.json只在内存中维护
basicMetrics := map[string]interface{}{ // 只持久化累计型数据
"uptime": stats["uptime"],
"total_bytes": stats["total_bytes"],
"avg_response_time": stats["avg_response_time"],
"save_time": time.Now().Format(time.RFC3339),
}
// 单独保存延迟统计,避免嵌套结构导致的内存占用
if latencyStats, ok := stats["latency_stats"].(map[string]interface{}); ok {
basicMetrics["latency_min"] = latencyStats["min"]
basicMetrics["latency_max"] = latencyStats["max"]
}
if err := saveJSONToFile(ms.metricsFile, basicMetrics); err != nil {
return fmt.Errorf("保存基本指标失败: %v", err)
}
// 保存状态码统计 // 保存状态码统计
if err := saveJSONToFile(ms.statusCodeFile, stats["status_code_stats"]); err != nil { if err := saveJSONToFile(ms.statusCodeFile, stats["status_code_stats"]); err != nil {
@ -163,24 +146,9 @@ func (ms *MetricsStorage) LoadMetrics() error {
start := time.Now() start := time.Now()
log.Printf("[MetricsStorage] 开始加载指标数据...") log.Printf("[MetricsStorage] 开始加载指标数据...")
// 检查文件是否存在 // 不再加载 basicMetricsmetrics.json
if !fileExists(ms.metricsFile) {
return fmt.Errorf("指标数据文件不存在")
}
// 加载基本指标 // 1. 加载状态码统计(如果文件存在)
var basicMetrics map[string]interface{}
if err := loadJSONFromFile(ms.metricsFile, &basicMetrics); err != nil {
return fmt.Errorf("加载基本指标失败: %v", err)
}
// 将加载的数据应用到收集器
// 1. 应用总字节数
if totalBytes, ok := basicMetrics["total_bytes"].(float64); ok {
atomic.StoreInt64(&ms.collector.totalBytes, int64(totalBytes))
}
// 2. 加载状态码统计(如果文件存在)
if fileExists(ms.statusCodeFile) { if fileExists(ms.statusCodeFile) {
var statusCodeStats map[string]interface{} var statusCodeStats map[string]interface{}
if err := loadJSONFromFile(ms.statusCodeFile, &statusCodeStats); err != nil { if err := loadJSONFromFile(ms.statusCodeFile, &statusCodeStats); err != nil {
@ -205,7 +173,7 @@ func (ms *MetricsStorage) LoadMetrics() error {
} }
} }
// 3. 加载引用来源统计(如果文件存在) // 2. 加载引用来源统计(如果文件存在)
if fileExists(ms.refererStatsFile) { if fileExists(ms.refererStatsFile) {
var refererStats []map[string]interface{} var refererStats []map[string]interface{}
if err := loadJSONFromFile(ms.refererStatsFile, &refererStats); err != nil { if err := loadJSONFromFile(ms.refererStatsFile, &refererStats); err != nil {
@ -245,7 +213,7 @@ func (ms *MetricsStorage) LoadMetrics() error {
} }
} }
// 5. 加载延迟分布(如果文件存在) // 3. 加载延迟分布(如果文件存在)
latencyDistributionFile := filepath.Join(ms.dataDir, "latency_distribution.json") latencyDistributionFile := filepath.Join(ms.dataDir, "latency_distribution.json")
if fileExists(latencyDistributionFile) { if fileExists(latencyDistributionFile) {
var distribution map[string]interface{} var distribution map[string]interface{}
@ -267,11 +235,7 @@ func (ms *MetricsStorage) LoadMetrics() error {
} }
ms.mutex.Lock() ms.mutex.Lock()
if saveTime, ok := basicMetrics["save_time"].(string); ok { // 不再恢复 lastSaveTimemetrics.json 里才有)
if t, err := time.Parse(time.RFC3339, saveTime); err == nil {
ms.lastSaveTime = t
}
}
ms.mutex.Unlock() ms.mutex.Unlock()
// 强制进行一次GC // 强制进行一次GC

View File

@ -188,7 +188,10 @@ export default function DashboardPage() {
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle></CardTitle> <CardTitle>
<span className="ml-2 text-sm font-normal text-gray-500 align-middle">(: {Object.values(metrics.status_code_stats || {}).reduce((a, b) => a + (b as number), 0)})</span>
</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-2 md:grid-cols-5 gap-4"> <div className="grid grid-cols-2 md:grid-cols-5 gap-4">