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"` RequestsPerSecond float64 `json:"requests_per_second"`
// 新增字段 // 新增字段
TotalBytes int64 `json:"total_bytes"` TotalBytes int64 `json:"total_bytes"`
BytesPerSecond float64 `json:"bytes_per_second"` BytesPerSecond float64 `json:"bytes_per_second"`
StatusCodeStats map[string]int64 `json:"status_code_stats"` StatusCodeStats map[string]int64 `json:"status_code_stats"`
TopPaths []models.PathMetrics `json:"top_paths"` TopPaths []models.PathMetricsJSON `json:"top_paths"`
RecentRequests []models.RequestLog `json:"recent_requests"` RecentRequests []models.RequestLog `json:"recent_requests"`
TopReferers []models.PathMetrics `json:"top_referers"` TopReferers []models.PathMetricsJSON `json:"top_referers"`
} }
// MetricsHandler 处理指标请求 // 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 { for i, metric := range pathMetrics {
pathMetricsValues[i] = models.PathMetrics{ pathMetricsValues[i] = metric.ToJSON()
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())
} }
// 收集延迟分布 // 收集延迟分布

View File

@ -21,6 +21,15 @@ type PathMetrics struct {
AvgLatency string `json:"avg_latency"` 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 获取请求数 // GetRequestCount 获取请求数
func (p *PathMetrics) GetRequestCount() int64 { func (p *PathMetrics) GetRequestCount() int64 {
return p.RequestCount.Load() return p.RequestCount.Load()
@ -61,6 +70,17 @@ func (p *PathMetrics) AddBytes(bytes int64) {
p.BytesTransferred.Add(bytes) 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 { type HistoricalMetrics struct {
Timestamp string `json:"timestamp"` Timestamp string `json:"timestamp"`
TotalRequests int64 `json:"total_requests"` TotalRequests int64 `json:"total_requests"`

View File

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