diff --git a/monitoring/metrics.go b/monitoring/metrics.go index 6eb3d95..51c79f4 100644 --- a/monitoring/metrics.go +++ b/monitoring/metrics.go @@ -1,11 +1,9 @@ package monitoring import ( - "encoding/json" "runtime" "strings" "sync" - "sync/atomic" "time" ) @@ -15,70 +13,58 @@ type SystemMetrics struct { StartTime time.Time `json:"start_time"` // 系统指标 - NumCPU int `json:"num_cpu"` - NumGoroutine int `json:"num_goroutine"` - MemoryStats struct { - Alloc uint64 `json:"alloc"` - TotalAlloc uint64 `json:"total_alloc"` - Sys uint64 `json:"sys"` - HeapAlloc uint64 `json:"heap_alloc"` - HeapSys uint64 `json:"heap_sys"` + NumCPU int `json:"num_cpu"` + NumGoroutine int `json:"num_goroutine"` + AverageLatency float64 `json:"average_latency"` + MemoryStats struct { + HeapAlloc uint64 `json:"heap_alloc"` + HeapSys uint64 `json:"heap_sys"` } `json:"memory_stats"` - // 性能指标 - RequestCount atomic.Int64 `json:"request_count"` - AverageLatency float64 `json:"average_latency"` - - // 流量统计 - TotalBytesIn int64 `json:"total_bytes_in"` - TotalBytesOut int64 `json:"total_bytes_out"` - - // 状态码统计 - StatusCodes map[int]int64 `json:"status_codes"` - - // 路径延迟统计 - PathLatencies map[string]float64 `json:"path_latencies"` - // 热门引用来源 - TopReferers map[string]int64 `json:"top_referers"` - - // 添加性能监控指标 - GCStats struct { - NumGC uint32 `json:"num_gc"` - PauseTotal float64 `json:"pause_total"` - PauseAvg float64 `json:"pause_avg"` - } `json:"gc_stats"` - - CPUUsage float64 `json:"cpu_usage"` - ThreadCount int `json:"thread_count"` + TopReferers sync.Map `json:"-"` // 使用 sync.Map 足够了 } type RequestLog struct { - Time int64 `json:"time"` // 使用 Unix 时间戳 - Path string `json:"path"` // 考虑使用字符串池 - Method string `json:"method"` // 使用常量池 + Time int64 `json:"time"` + Path string `json:"path"` + Method string `json:"method"` StatusCode int `json:"status_code"` - Latency float64 `json:"latency"` // 改回 float64,保持一致性 + Latency float64 `json:"latency"` IP string `json:"ip"` Referer string `json:"referer"` } var ( metrics SystemMetrics - mu sync.RWMutex startTime = time.Now() ) func init() { - metrics.StatusCodes = make(map[int]int64) - metrics.PathLatencies = make(map[string]float64) - metrics.TopReferers = make(map[string]int64) + // 定期清理引用来源 + go func() { + ticker := time.NewTicker(5 * time.Minute) + for range ticker.C { + metrics.TopReferers = sync.Map{} // 直接重置 + } + }() +} + +func LogRequest(log RequestLog) { + // 更新引用来源 + if log.Referer != "direct" { + metrics.TopReferers.Store(log.Referer, 1) + } else { + metrics.TopReferers.Store("直接访问", 1) + } + + // 更新平均延迟 (只关心 API 请求) + if strings.HasPrefix(log.Path, "/pic/") || strings.HasPrefix(log.Path, "/video/") { + metrics.AverageLatency = (metrics.AverageLatency + log.Latency) / 2 + } } func CollectMetrics() *SystemMetrics { - mu.Lock() - defer mu.Unlock() - var m runtime.MemStats runtime.ReadMemStats(&m) @@ -86,74 +72,8 @@ func CollectMetrics() *SystemMetrics { metrics.StartTime = startTime metrics.NumCPU = runtime.NumCPU() metrics.NumGoroutine = runtime.NumGoroutine() - - metrics.MemoryStats.Alloc = m.Alloc - metrics.MemoryStats.TotalAlloc = m.TotalAlloc - metrics.MemoryStats.Sys = m.Sys metrics.MemoryStats.HeapAlloc = m.HeapAlloc metrics.MemoryStats.HeapSys = m.HeapSys return &metrics } - -func LogRequest(log RequestLog) { - metrics.RequestCount.Add(1) - - mu.Lock() // 添加全局锁保护 map 写入 - metrics.StatusCodes[log.StatusCode]++ - - // 直接使用完整的 referer - if log.Referer != "direct" { - metrics.TopReferers[log.Referer]++ - } else { - metrics.TopReferers["直接访问"]++ - } - mu.Unlock() - - // 只记录 API 请求 - if strings.HasPrefix(log.Path, "/pic/") || strings.HasPrefix(log.Path, "/video/") { - // 更新路径延迟 - mu.Lock() // 保护 PathLatencies map - if existing, ok := metrics.PathLatencies[log.Path]; ok { - metrics.PathLatencies[log.Path] = (existing + log.Latency) / 2 - } else { - metrics.PathLatencies[log.Path] = log.Latency - } - mu.Unlock() - - // 更新平均延迟 - count := metrics.RequestCount.Load() - if count > 1 { - metrics.AverageLatency = (metrics.AverageLatency*(float64(count)-1) + log.Latency) / float64(count) - } else { - metrics.AverageLatency = log.Latency - } - } -} - -// 添加分段锁结构 -type bucket struct { - mu sync.Mutex -} - -var buckets = make([]bucket, 32) - -func getBucket(path string) *bucket { - hash := uint32(0) - for i := 0; i < len(path); i++ { - hash = hash*31 + uint32(path[i]) - } - return &buckets[hash%32] -} - -// 添加 MarshalJSON 方法 -func (m *SystemMetrics) MarshalJSON() ([]byte, error) { - type Alias SystemMetrics - return json.Marshal(&struct { - RequestCount int64 `json:"request_count"` - *Alias - }{ - RequestCount: m.RequestCount.Load(), - Alias: (*Alias)(m), - }) -} diff --git a/public/index.html b/public/index.html index c0b8da2..624234a 100644 --- a/public/index.html +++ b/public/index.html @@ -21,6 +21,7 @@