mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 08:31:55 +08:00
feat(metrics): 添加引用来源统计持久化支持
- 在 MetricsStorage 结构体中新增 refererStatsFile 字段 - 在 SaveMetrics 方法中添加引用来源统计保存逻辑 - 在 LoadMetrics 方法中实现引用来源统计的加载和恢复 - 前端页面调整路径显示,增加长路径的截断处理 - 优化引用来源统计的数据处理和类型转换
This commit is contained in:
parent
d2e5020d22
commit
2a41458bb8
@ -14,16 +14,17 @@ import (
|
||||
|
||||
// MetricsStorage 指标存储结构
|
||||
type MetricsStorage struct {
|
||||
collector *Collector
|
||||
saveInterval time.Duration
|
||||
dataDir string
|
||||
stopChan chan struct{}
|
||||
wg sync.WaitGroup
|
||||
lastSaveTime time.Time
|
||||
mutex sync.RWMutex
|
||||
metricsFile string
|
||||
pathStatsFile string
|
||||
statusCodeFile string
|
||||
collector *Collector
|
||||
saveInterval time.Duration
|
||||
dataDir string
|
||||
stopChan chan struct{}
|
||||
wg sync.WaitGroup
|
||||
lastSaveTime time.Time
|
||||
mutex sync.RWMutex
|
||||
metricsFile string
|
||||
pathStatsFile string
|
||||
statusCodeFile string
|
||||
refererStatsFile string
|
||||
}
|
||||
|
||||
// NewMetricsStorage 创建新的指标存储
|
||||
@ -33,13 +34,14 @@ func NewMetricsStorage(collector *Collector, dataDir string, saveInterval time.D
|
||||
}
|
||||
|
||||
return &MetricsStorage{
|
||||
collector: collector,
|
||||
saveInterval: saveInterval,
|
||||
dataDir: dataDir,
|
||||
stopChan: make(chan struct{}),
|
||||
metricsFile: filepath.Join(dataDir, "metrics.json"),
|
||||
pathStatsFile: filepath.Join(dataDir, "path_stats.json"),
|
||||
statusCodeFile: filepath.Join(dataDir, "status_codes.json"),
|
||||
collector: collector,
|
||||
saveInterval: saveInterval,
|
||||
dataDir: dataDir,
|
||||
stopChan: make(chan struct{}),
|
||||
metricsFile: filepath.Join(dataDir, "metrics.json"),
|
||||
pathStatsFile: filepath.Join(dataDir, "path_stats.json"),
|
||||
statusCodeFile: filepath.Join(dataDir, "status_codes.json"),
|
||||
refererStatsFile: filepath.Join(dataDir, "referer_stats.json"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +131,11 @@ func (ms *MetricsStorage) SaveMetrics() error {
|
||||
return fmt.Errorf("保存状态码统计失败: %v", err)
|
||||
}
|
||||
|
||||
// 保存引用来源统计
|
||||
if err := saveJSONToFile(ms.refererStatsFile, stats["top_referers"]); err != nil {
|
||||
return fmt.Errorf("保存引用来源统计失败: %v", err)
|
||||
}
|
||||
|
||||
ms.mutex.Lock()
|
||||
ms.lastSaveTime = time.Now()
|
||||
ms.mutex.Unlock()
|
||||
@ -165,6 +172,17 @@ func (ms *MetricsStorage) LoadMetrics() error {
|
||||
return fmt.Errorf("加载状态码统计失败: %v", err)
|
||||
}
|
||||
|
||||
// 加载引用来源统计(如果文件存在)
|
||||
var refererStats []map[string]interface{}
|
||||
if fileExists(ms.refererStatsFile) {
|
||||
if err := loadJSONFromFile(ms.refererStatsFile, &refererStats); err != nil {
|
||||
log.Printf("[MetricsStorage] 加载引用来源统计失败: %v", err)
|
||||
// 不中断加载过程
|
||||
} else {
|
||||
log.Printf("[MetricsStorage] 成功加载引用来源统计: %d 条记录", len(refererStats))
|
||||
}
|
||||
}
|
||||
|
||||
// 将加载的数据应用到收集器
|
||||
// 1. 应用总字节数
|
||||
if totalBytes, ok := basicMetrics["total_bytes"].(float64); ok {
|
||||
@ -214,6 +232,35 @@ func (ms *MetricsStorage) LoadMetrics() error {
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 应用引用来源统计
|
||||
if len(refererStats) > 0 {
|
||||
for _, refererStat := range refererStats {
|
||||
referer, ok := refererStat["path"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
requestCount, _ := refererStat["request_count"].(float64)
|
||||
errorCount, _ := refererStat["error_count"].(float64)
|
||||
bytesTransferred, _ := refererStat["bytes_transferred"].(float64)
|
||||
|
||||
// 创建或更新引用来源统计
|
||||
var refererMetrics *models.PathMetrics
|
||||
if existingMetrics, ok := ms.collector.refererStats.Load(referer); ok {
|
||||
refererMetrics = existingMetrics.(*models.PathMetrics)
|
||||
} else {
|
||||
refererMetrics = &models.PathMetrics{Path: referer}
|
||||
ms.collector.refererStats.Store(referer, refererMetrics)
|
||||
}
|
||||
|
||||
// 设置统计值
|
||||
refererMetrics.RequestCount.Store(int64(requestCount))
|
||||
refererMetrics.ErrorCount.Store(int64(errorCount))
|
||||
refererMetrics.BytesTransferred.Store(int64(bytesTransferred))
|
||||
}
|
||||
log.Printf("[MetricsStorage] 应用了 %d 条引用来源统计记录", len(refererStats))
|
||||
}
|
||||
|
||||
// 4. 应用延迟分布桶(如果有)
|
||||
if latencyStats, ok := basicMetrics["latency_stats"].(map[string]interface{}); ok {
|
||||
if distribution, ok := latencyStats["distribution"].(map[string]interface{}); ok {
|
||||
|
@ -274,6 +274,7 @@ export default function DashboardPage() {
|
||||
let displayRange = range;
|
||||
if (range === "lt10ms") displayRange = "<10ms";
|
||||
if (range === "gt1s") displayRange = ">1s";
|
||||
if (range === "200-1000ms") displayRange = "0.2-1s";
|
||||
|
||||
return (
|
||||
<div key={range} className="p-3 rounded-lg border bg-card text-card-foreground shadow-sm">
|
||||
@ -404,7 +405,7 @@ export default function DashboardPage() {
|
||||
<tbody>
|
||||
{metrics.top_referers.map((referer, index) => (
|
||||
<tr key={index} className="border-b">
|
||||
<td className="p-2">
|
||||
<td className="p-2 max-w-xs truncate">
|
||||
<span className="text-blue-600">
|
||||
{referer.path}
|
||||
</span>
|
||||
@ -441,7 +442,7 @@ export default function DashboardPage() {
|
||||
<tbody>
|
||||
{(metrics.top_paths || []).map((path, index) => (
|
||||
<tr key={index} className="border-b">
|
||||
<td className="p-2">
|
||||
<td className="p-2 max-w-xs truncate">
|
||||
<a
|
||||
href={path.path}
|
||||
target="_blank"
|
||||
|
Loading…
x
Reference in New Issue
Block a user