mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 16:41:54 +08:00
feat(metrics): optimize stats collection and enhance error handling
- Refactored the GetStats method to improve memory management by utilizing an object pool for stats initialization. - Enhanced error rate calculation and added average response time metrics for better performance insights. - Streamlined path and referer statistics collection, ensuring only relevant data is processed and displayed. - Improved sorting and selection logic for top paths and referers, enhancing the clarity of metrics reporting. - Updated comments for better code readability and understanding of the metrics collection process. These changes enhance the efficiency and accuracy of the metrics collector, providing more reliable performance data and insights.
This commit is contained in:
parent
14843301f7
commit
f360e13ca3
@ -277,13 +277,15 @@ func (c *Collector) GetStats() map[string]interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 确保所有字段都被初始化
|
||||||
|
stats := c.statsPool.Get().(map[string]interface{})
|
||||||
|
defer c.statsPool.Put(stats)
|
||||||
|
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
runtime.ReadMemStats(&m)
|
runtime.ReadMemStats(&m)
|
||||||
|
|
||||||
// 确保所有字段都被初始化
|
// 基础指标
|
||||||
stats := make(map[string]interface{})
|
uptime := time.Since(c.startTime)
|
||||||
|
|
||||||
// 基础指标 - 合并当前会话和持久化的数据
|
|
||||||
currentRequests := atomic.LoadInt64(&c.totalRequests)
|
currentRequests := atomic.LoadInt64(&c.totalRequests)
|
||||||
currentErrors := atomic.LoadInt64(&c.totalErrors)
|
currentErrors := atomic.LoadInt64(&c.totalErrors)
|
||||||
currentBytes := c.totalBytes.Load()
|
currentBytes := c.totalBytes.Load()
|
||||||
@ -292,98 +294,97 @@ func (c *Collector) GetStats() map[string]interface{} {
|
|||||||
totalErrors := currentErrors + c.persistentStats.totalErrors.Load()
|
totalErrors := currentErrors + c.persistentStats.totalErrors.Load()
|
||||||
totalBytes := currentBytes + c.persistentStats.totalBytes.Load()
|
totalBytes := currentBytes + c.persistentStats.totalBytes.Load()
|
||||||
|
|
||||||
// 计算每秒指标
|
// 计算错误率
|
||||||
uptime := time.Since(c.startTime).Seconds()
|
var errorRate float64
|
||||||
stats["requests_per_second"] = float64(currentRequests) / Max(uptime, 1)
|
if totalRequests > 0 {
|
||||||
stats["bytes_per_second"] = float64(currentBytes) / Max(uptime, 1)
|
errorRate = float64(totalErrors) / float64(totalRequests)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基础指标
|
||||||
|
stats["uptime"] = uptime.String()
|
||||||
stats["active_requests"] = atomic.LoadInt64(&c.activeRequests)
|
stats["active_requests"] = atomic.LoadInt64(&c.activeRequests)
|
||||||
stats["total_requests"] = totalRequests
|
stats["total_requests"] = totalRequests
|
||||||
stats["total_errors"] = totalErrors
|
stats["total_errors"] = totalErrors
|
||||||
|
stats["error_rate"] = errorRate
|
||||||
stats["total_bytes"] = totalBytes
|
stats["total_bytes"] = totalBytes
|
||||||
|
stats["bytes_per_second"] = float64(currentBytes) / Max(uptime.Seconds(), 1)
|
||||||
|
stats["requests_per_second"] = float64(currentRequests) / Max(uptime.Seconds(), 1)
|
||||||
|
|
||||||
// 系统指标
|
// 系统指标
|
||||||
stats["num_goroutine"] = runtime.NumGoroutine()
|
stats["num_goroutine"] = runtime.NumGoroutine()
|
||||||
stats["memory_usage"] = FormatBytes(m.Alloc)
|
stats["memory_usage"] = FormatBytes(m.Alloc)
|
||||||
|
|
||||||
// 延迟指标
|
// 延迟指标
|
||||||
currentTotalRequests := atomic.LoadInt64(&c.totalRequests)
|
|
||||||
latencySum := c.latencySum.Load()
|
latencySum := c.latencySum.Load()
|
||||||
if currentTotalRequests <= 0 || latencySum <= 0 {
|
if currentRequests > 0 {
|
||||||
stats["avg_latency"] = int64(0)
|
stats["avg_response_time"] = FormatDuration(time.Duration(latencySum / currentRequests))
|
||||||
} else {
|
} else {
|
||||||
stats["avg_latency"] = latencySum / currentTotalRequests
|
stats["avg_response_time"] = FormatDuration(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 状态码统计
|
// 状态码统计
|
||||||
statusStats := make(map[string]int64)
|
statusStats := make(map[string]int64)
|
||||||
for i := range c.statusStats {
|
for i := range c.statusStats {
|
||||||
if i < len(c.statusStats) {
|
statusStats[fmt.Sprintf("%dxx", i+1)] = c.statusStats[i].Load()
|
||||||
statusStats[fmt.Sprintf("%dxx", i+1)] = c.statusStats[i].Load()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stats["status_code_stats"] = statusStats
|
stats["status_code_stats"] = statusStats
|
||||||
|
|
||||||
// 获取Top 10路径统计
|
// 延迟百分位数
|
||||||
var pathMetrics []models.PathMetrics
|
stats["latency_percentiles"] = make([]float64, 0)
|
||||||
var allPaths []models.PathMetrics
|
|
||||||
|
|
||||||
|
// 路径统计
|
||||||
|
var pathMetrics []models.PathMetrics
|
||||||
c.pathStats.Range(func(key, value interface{}) bool {
|
c.pathStats.Range(func(key, value interface{}) bool {
|
||||||
stats := value.(*models.PathStats)
|
stats := value.(*models.PathStats)
|
||||||
if stats.Requests.Load() == 0 {
|
if stats.Requests.Load() > 0 {
|
||||||
return true
|
pathMetrics = append(pathMetrics, models.PathMetrics{
|
||||||
|
Path: key.(string),
|
||||||
|
RequestCount: stats.Requests.Load(),
|
||||||
|
ErrorCount: stats.Errors.Load(),
|
||||||
|
AvgLatency: formatAvgLatency(stats.LatencySum.Load(), stats.Requests.Load()),
|
||||||
|
BytesTransferred: stats.Bytes.Load(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
allPaths = append(allPaths, models.PathMetrics{
|
|
||||||
Path: key.(string),
|
|
||||||
RequestCount: stats.Requests.Load(),
|
|
||||||
ErrorCount: stats.Errors.Load(),
|
|
||||||
AvgLatency: formatAvgLatency(stats.LatencySum.Load(), stats.Requests.Load()),
|
|
||||||
BytesTransferred: stats.Bytes.Load(),
|
|
||||||
})
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
// 按请求数排序并获取前10个
|
// 按请求数排序
|
||||||
sort.Slice(allPaths, func(i, j int) bool {
|
sort.Slice(pathMetrics, func(i, j int) bool {
|
||||||
return allPaths[i].RequestCount > allPaths[j].RequestCount
|
return pathMetrics[i].RequestCount > pathMetrics[j].RequestCount
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(allPaths) > 10 {
|
if len(pathMetrics) > 10 {
|
||||||
pathMetrics = allPaths[:10]
|
stats["top_paths"] = pathMetrics[:10]
|
||||||
} else {
|
} else {
|
||||||
pathMetrics = allPaths
|
stats["top_paths"] = pathMetrics
|
||||||
}
|
}
|
||||||
stats["top_paths"] = pathMetrics
|
|
||||||
|
|
||||||
// 获取最近请求
|
// 最近请求
|
||||||
stats["recent_requests"] = c.getRecentRequests()
|
stats["recent_requests"] = c.getRecentRequests()
|
||||||
|
|
||||||
// 获取Top 10引用来源
|
// 引用来源统计
|
||||||
var refererMetrics []models.PathMetrics
|
var refererMetrics []models.PathMetrics
|
||||||
var allReferers []models.PathMetrics
|
|
||||||
c.refererStats.Range(func(key, value interface{}) bool {
|
c.refererStats.Range(func(key, value interface{}) bool {
|
||||||
stats := value.(*models.PathStats)
|
stats := value.(*models.PathStats)
|
||||||
if stats.Requests.Load() == 0 {
|
if stats.Requests.Load() > 0 {
|
||||||
return true
|
refererMetrics = append(refererMetrics, models.PathMetrics{
|
||||||
|
Path: key.(string),
|
||||||
|
RequestCount: stats.Requests.Load(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
allReferers = append(allReferers, models.PathMetrics{
|
|
||||||
Path: key.(string),
|
|
||||||
RequestCount: stats.Requests.Load(),
|
|
||||||
})
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
// 按请求数排序并获取前10个
|
// 按请求数排序
|
||||||
sort.Slice(allReferers, func(i, j int) bool {
|
sort.Slice(refererMetrics, func(i, j int) bool {
|
||||||
return allReferers[i].RequestCount > allReferers[j].RequestCount
|
return refererMetrics[i].RequestCount > refererMetrics[j].RequestCount
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(allReferers) > 10 {
|
if len(refererMetrics) > 10 {
|
||||||
refererMetrics = allReferers[:10]
|
stats["top_referers"] = refererMetrics[:10]
|
||||||
} else {
|
} else {
|
||||||
refererMetrics = allReferers
|
stats["top_referers"] = refererMetrics
|
||||||
}
|
}
|
||||||
stats["top_referers"] = refererMetrics
|
|
||||||
|
|
||||||
// 检查告警
|
// 检查告警
|
||||||
c.monitor.CheckMetrics(stats)
|
c.monitor.CheckMetrics(stats)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user