refactor(metrics): Introduce JSON-friendly metrics serialization

- Create PathMetricsJSON struct for clean JSON serialization
- Add ToJSON method to convert PathMetrics to JSON-compatible representation
- Update metrics handlers and collectors to use new JSON-friendly type
- Simplify type conversion in SafePathMetrics utility function
- Improve metrics data transfer and serialization consistency
This commit is contained in:
wood chen 2025-02-17 08:01:29 +08:00
parent 55d3a9cebc
commit ed63121a00
4 changed files with 34 additions and 40 deletions

View File

@ -29,12 +29,12 @@ type Metrics struct {
RequestsPerSecond float64 `json:"requests_per_second"`
// 新增字段
TotalBytes int64 `json:"total_bytes"`
BytesPerSecond float64 `json:"bytes_per_second"`
StatusCodeStats map[string]int64 `json:"status_code_stats"`
TopPaths []models.PathMetrics `json:"top_paths"`
RecentRequests []models.RequestLog `json:"recent_requests"`
TopReferers []models.PathMetrics `json:"top_referers"`
TotalBytes int64 `json:"total_bytes"`
BytesPerSecond float64 `json:"bytes_per_second"`
StatusCodeStats map[string]int64 `json:"status_code_stats"`
TopPaths []models.PathMetricsJSON `json:"top_paths"`
RecentRequests []models.RequestLog `json:"recent_requests"`
TopReferers []models.PathMetricsJSON `json:"top_referers"`
}
// MetricsHandler 处理指标请求

View File

@ -265,20 +265,9 @@ func (c *Collector) GetStats() map[string]interface{} {
}
// 转换为值切片
pathMetricsValues := make([]models.PathMetrics, len(pathMetrics))
pathMetricsValues := make([]models.PathMetricsJSON, len(pathMetrics))
for i, metric := range pathMetrics {
pathMetricsValues[i] = models.PathMetrics{
Path: metric.Path,
AvgLatency: metric.AvgLatency,
RequestCount: atomic.Int64{},
ErrorCount: atomic.Int64{},
TotalLatency: atomic.Int64{},
BytesTransferred: atomic.Int64{},
}
pathMetricsValues[i].RequestCount.Store(metric.RequestCount.Load())
pathMetricsValues[i].ErrorCount.Store(metric.ErrorCount.Load())
pathMetricsValues[i].TotalLatency.Store(metric.TotalLatency.Load())
pathMetricsValues[i].BytesTransferred.Store(metric.BytesTransferred.Load())
pathMetricsValues[i] = metric.ToJSON()
}
// 收集延迟分布

View File

@ -21,6 +21,15 @@ type PathMetrics struct {
AvgLatency string `json:"avg_latency"`
}
// PathMetricsJSON 用于 JSON 序列化的路径统计信息
type PathMetricsJSON struct {
Path string `json:"path"`
RequestCount int64 `json:"request_count"`
ErrorCount int64 `json:"error_count"`
BytesTransferred int64 `json:"bytes_transferred"`
AvgLatency string `json:"avg_latency"`
}
// GetRequestCount 获取请求数
func (p *PathMetrics) GetRequestCount() int64 {
return p.RequestCount.Load()
@ -61,6 +70,17 @@ func (p *PathMetrics) AddBytes(bytes int64) {
p.BytesTransferred.Add(bytes)
}
// ToJSON 转换为 JSON 友好的结构
func (p *PathMetrics) ToJSON() PathMetricsJSON {
return PathMetricsJSON{
Path: p.Path,
RequestCount: p.RequestCount.Load(),
ErrorCount: p.ErrorCount.Load(),
BytesTransferred: p.BytesTransferred.Load(),
AvgLatency: p.AvgLatency,
}
}
type HistoricalMetrics struct {
Timestamp string `json:"timestamp"`
TotalRequests int64 `json:"total_requests"`

View File

@ -1,9 +1,5 @@
package models
import (
"sync/atomic"
)
// SafeStatusCodeStats 安全地将 interface{} 转换为状态码统计
func SafeStatusCodeStats(v interface{}) map[string]int64 {
if v == nil {
@ -16,32 +12,21 @@ func SafeStatusCodeStats(v interface{}) map[string]int64 {
}
// SafePathMetrics 安全地将 interface{} 转换为路径指标
func SafePathMetrics(v interface{}) []PathMetrics {
func SafePathMetrics(v interface{}) []PathMetricsJSON {
if v == nil {
return []PathMetrics{}
return []PathMetricsJSON{}
}
if m, ok := v.([]PathMetrics); ok {
if m, ok := v.([]PathMetricsJSON); ok {
return m
}
if m, ok := v.([]*PathMetrics); ok {
result := make([]PathMetrics, len(m))
result := make([]PathMetricsJSON, len(m))
for i, metric := range m {
result[i] = PathMetrics{
Path: metric.Path,
AvgLatency: metric.AvgLatency,
RequestCount: atomic.Int64{},
ErrorCount: atomic.Int64{},
TotalLatency: atomic.Int64{},
BytesTransferred: atomic.Int64{},
}
result[i].RequestCount.Store(metric.RequestCount.Load())
result[i].ErrorCount.Store(metric.ErrorCount.Load())
result[i].TotalLatency.Store(metric.TotalLatency.Load())
result[i].BytesTransferred.Store(metric.BytesTransferred.Load())
result[i] = metric.ToJSON()
}
return result
}
return []PathMetrics{}
return []PathMetricsJSON{}
}
// SafeRequestLogs 安全地将 interface{} 转换为请求日志