From d00ab0a6e168b515fe3da0108530db83b1bae767 Mon Sep 17 00:00:00 2001 From: wood chen Date: Sat, 15 Feb 2025 18:24:55 +0800 Subject: [PATCH] feat(metrics): Improve latency tracking and error visualization - Add atomic operations to track minimum and maximum request latency - Update GetStats method to handle uninitialized latency values - Modify dashboard error chart with improved color scheme and legend - Adjust chart margins and axis width for better readability --- internal/metrics/collector.go | 32 ++++++++++++++++++++++++++++++-- web/app/dashboard/page.tsx | 9 +++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/internal/metrics/collector.go b/internal/metrics/collector.go index ca4bab5..7c34920 100644 --- a/internal/metrics/collector.go +++ b/internal/metrics/collector.go @@ -88,6 +88,27 @@ func (c *Collector) RecordRequest(path string, status int, latency time.Duration atomic.AddInt64(&c.totalBytes, bytes) atomic.AddInt64(&c.latencySum, int64(latency)) + // 更新最小和最大响应时间 + latencyNanos := int64(latency) + for { + oldMin := atomic.LoadInt64(&c.minLatency) + if oldMin <= latencyNanos { + break + } + if atomic.CompareAndSwapInt64(&c.minLatency, oldMin, latencyNanos) { + break + } + } + for { + oldMax := atomic.LoadInt64(&c.maxLatency) + if oldMax >= latencyNanos { + break + } + if atomic.CompareAndSwapInt64(&c.maxLatency, oldMax, latencyNanos) { + break + } + } + // 更新延迟分布 latencyMs := latency.Milliseconds() var bucketKey string @@ -245,6 +266,13 @@ func (c *Collector) GetStats() map[string]interface{} { } } + // 获取最小和最大响应时间 + minLatency := atomic.LoadInt64(&c.minLatency) + maxLatency := atomic.LoadInt64(&c.maxLatency) + if minLatency == math.MaxInt64 { + minLatency = 0 + } + return map[string]interface{}{ "uptime": time.Since(c.startTime).String(), "active_requests": atomic.LoadInt64(&c.activeRequests), @@ -258,8 +286,8 @@ func (c *Collector) GetStats() map[string]interface{} { "top_paths": pathMetrics, "recent_requests": c.recentRequests, "latency_stats": map[string]interface{}{ - "min": fmt.Sprintf("%.2fms", float64(atomic.LoadInt64(&c.minLatency))/float64(time.Millisecond)), - "max": fmt.Sprintf("%.2fms", float64(atomic.LoadInt64(&c.maxLatency))/float64(time.Millisecond)), + "min": fmt.Sprintf("%.2fms", float64(minLatency)/float64(time.Millisecond)), + "max": fmt.Sprintf("%.2fms", float64(maxLatency)/float64(time.Millisecond)), "distribution": latencyDistribution, }, "error_stats": map[string]interface{}{ diff --git a/web/app/dashboard/page.tsx b/web/app/dashboard/page.tsx index 9c72d90..aadcea4 100644 --- a/web/app/dashboard/page.tsx +++ b/web/app/dashboard/page.tsx @@ -61,7 +61,7 @@ interface Metrics { } // 颜色常量 -const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884d8'] +const COLORS = ['#0088FE', '#FF8042', '#00C49F', '#FFBB28', '#FF0000'] export default function DashboardPage() { const [metrics, setMetrics] = useState(null) @@ -395,13 +395,14 @@ export default function DashboardPage() { value, }))} layout="vertical" - margin={{ top: 5, right: 30, left: 100, bottom: 5 }} + margin={{ top: 5, right: 30, left: 120, bottom: 5 }} > - + - + +