This commit is contained in:
wood chen 2024-12-05 08:23:38 +08:00
parent 97a195c9dd
commit 864ebcc610
2 changed files with 30 additions and 35 deletions

View File

@ -389,41 +389,35 @@ var metricsTemplate = `
} }
+ #statusCodes { + #statusCodes {
+ display: flex; + display: flex;
+ gap: 20px; + flex-direction: column;
+ align-items: center; + gap: 10px;
+ flex-wrap: wrap; + align-items: flex-start;
+ padding: 10px; + padding: 10px;
+ justify-content: flex-start;
+ background: #f8f9fa; + background: #f8f9fa;
+ border-radius: 8px; + border-radius: 8px;
+ overflow-x: auto; + flex-wrap: nowrap; // 防止换行
+ white-space: nowrap; + overflow-x: auto; // 在小屏幕上可以滚动
+ } + }
+ +
+ #statusCodes .metric { + #statusCodes .metric {
+ flex: 0 0 auto; + flex: 0 0 auto; // 不伸缩,保持原始大小
+ display: inline-flex; + display: flex;
+ align-items: center; + align-items: center;
+ gap: 10px; + justify-content: space-between;
+ padding: 4px 12px; + padding: 4px 12px;
+ background: white; + background: white;
+ border-radius: 20px; + border-radius: 4px;
+ margin: 0; + box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+ border: none; + min-width: 120px; // 设置最小宽度
+ min-width: 80px; + margin-right: 10px; // 格子之间的间距
+ justify-content: space-between;
+ margin-right: 10px;
+ display: inline-block;
+ } + }
+ #statusCodes .metric:last-child { + .status-badge {
+ margin-right: 0; + padding: 3px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ color: white;
+ margin-right: 8px; // 状态码和数字之间的间距
+ } + }
.status-badge {
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
color: white;
}
+ .loading { + .loading {
+ position: relative; + position: relative;
+ opacity: 0.6; + opacity: 0.6;

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"log" "log"
"math/rand"
"net/http" "net/http"
"proxy-go/internal/cache" "proxy-go/internal/cache"
"proxy-go/internal/config" "proxy-go/internal/config"
@ -91,26 +92,25 @@ func InitCollector(dbPath string, config *config.Config) error {
// 启动定时保存 // 启动定时保存
go func() { go func() {
ticker := time.NewTicker(5 * time.Minute) // 避免所有实例同时保存
time.Sleep(time.Duration(rand.Int63n(60)) * time.Second)
ticker := time.NewTicker(10 * time.Minute)
for range ticker.C { for range ticker.C {
stats := globalCollector.GetStats() stats := globalCollector.GetStats()
start := time.Now()
// 保存基础指标和完整统计数据
if err := db.SaveMetrics(stats); err != nil { if err := db.SaveMetrics(stats); err != nil {
log.Printf("Error saving metrics: %v", err) log.Printf("Error saving metrics: %v", err)
} else { } else {
log.Printf("Metrics saved successfully") log.Printf("Basic metrics saved successfully")
} }
}
}()
// 启动每小时保存统计数据 // 同时保存完整统计数据
go func() {
ticker := time.NewTicker(1 * time.Hour)
for range ticker.C {
stats := globalCollector.GetStats()
if err := db.SaveFullMetrics(stats); err != nil { if err := db.SaveFullMetrics(stats); err != nil {
log.Printf("Error saving full metrics: %v", err) log.Printf("Error saving full metrics: %v", err)
} else { } else {
log.Printf("Full metrics saved successfully") log.Printf("Metrics saved in %v", time.Since(start))
} }
} }
}() }()
@ -292,8 +292,9 @@ func (c *Collector) GetStats() map[string]interface{} {
// 状态码统计 // 状态码统计
statusStats := make(map[string]int64) statusStats := make(map[string]int64)
statusGroups := []string{"1xx", "2xx", "3xx", "4xx", "5xx"}
for i := range c.statusStats { for i := range c.statusStats {
statusStats[fmt.Sprintf("%dxx", i+1)] = c.statusStats[i].Load() statusStats[statusGroups[i]] = c.statusStats[i].Load()
} }
stats["status_code_stats"] = statusStats stats["status_code_stats"] = statusStats