From 44c01d39d09681b46731bca68fbb4de1cdb801b7 Mon Sep 17 00:00:00 2001 From: Crimson Date: Sat, 9 May 2026 16:07:54 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=87=D0=B8=D1=82=D1=8C=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D1=83=207=20=D0=B4=D0=BD=D1=8F=D0=BC=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D1=83=D0=B1=D1=80=D0=B0=D1=82=D1=8C=2030d=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=B4=D0=B0=D1=88=D0=B1=D0=BE=D1=80=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dao/traffic.go | 33 +++++++++++++++++++++ apps/frontend/src/views/dashboard/index.vue | 1 - apps/middleware/cron.go | 6 ++-- apps/service/cron.go | 2 -- apps/service/dashboard.go | 25 ++++++++-------- apps/service/metrics_collector.go | 17 +++++++++-- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/apps/dao/traffic.go b/apps/dao/traffic.go index 44ba868..f1e9202 100644 --- a/apps/dao/traffic.go +++ b/apps/dao/traffic.go @@ -67,3 +67,36 @@ func UpsertTrafficAggregateDaily(peerId int64, dayStart int64, rxBytes int64, tx func gormExprAdd(column string, delta int64) interface{} { return gorm.Expr(fmt.Sprintf("%s + ?", column), delta) } + +func CleanupTrafficSample(olderThanMs int64) error { + if !tableExists("traffic_sample") { + return nil + } + if tx := sqliteDB.Exec("DELETE FROM traffic_sample WHERE sampled_at < ?", olderThanMs); tx.Error != nil { + logrus.Errorf("%v", tx.Error) + return errors.New(constant.SysError) + } + return nil +} + +func CleanupTrafficAggregateHourly(olderThanMs int64) error { + if !tableExists("traffic_aggregate_hourly") { + return nil + } + if tx := sqliteDB.Exec("DELETE FROM traffic_aggregate_hourly WHERE hour_start < ?", olderThanMs); tx.Error != nil { + logrus.Errorf("%v", tx.Error) + return errors.New(constant.SysError) + } + return nil +} + +func CleanupTrafficAggregateDaily(olderThanMs int64) error { + if !tableExists("traffic_aggregate_daily") { + return nil + } + if tx := sqliteDB.Exec("DELETE FROM traffic_aggregate_daily WHERE day_start < ?", olderThanMs); tx.Error != nil { + logrus.Errorf("%v", tx.Error) + return errors.New(constant.SysError) + } + return nil +} diff --git a/apps/frontend/src/views/dashboard/index.vue b/apps/frontend/src/views/dashboard/index.vue index d71a638..0f15098 100644 --- a/apps/frontend/src/views/dashboard/index.vue +++ b/apps/frontend/src/views/dashboard/index.vue @@ -47,7 +47,6 @@ 1h 24h 7d - 30d diff --git a/apps/middleware/cron.go b/apps/middleware/cron.go index c73f530..71dfc80 100644 --- a/apps/middleware/cron.go +++ b/apps/middleware/cron.go @@ -23,10 +23,10 @@ func InitCron() error { logrus.Errorf("cron add func CollectMetricsSnapshot err: %v", err) return errors.New("cron add func CollectMetricsSnapshot err") } - _, err = c.AddFunc("@every 10m", service.CleanupMetricsRetention) + _, err = c.AddFunc("@every 1h", service.CleanupStatsRetention) if err != nil { - logrus.Errorf("cron add func CleanupMetricsRetention err: %v", err) - return errors.New("cron add func CleanupMetricsRetention err") + logrus.Errorf("cron add func CleanupStatsRetention err: %v", err) + return errors.New("cron add func CleanupStatsRetention err") } resetTrafficCron, err := dao.GetConfig("key = ?", constant.ResetTrafficCron) if err != nil { diff --git a/apps/service/cron.go b/apps/service/cron.go index 9c96a39..7711ac5 100644 --- a/apps/service/cron.go +++ b/apps/service/cron.go @@ -72,7 +72,6 @@ func saveAccountTraffic(apiPort int64, trafficStatsSecret string) { nowMs := time.Now().UnixMilli() hourStart := nowMs - (nowMs % int64(time.Hour/time.Millisecond)) - dayStart := nowMs - (nowMs % int64(24*time.Hour/time.Millisecond)) for key, traffic := range users { rxBytes := traffic.Rx @@ -115,7 +114,6 @@ func saveAccountTraffic(apiPort int64, trafficStatsSecret string) { } _ = dao.UpsertTrafficAggregateHourly(*peer.Id, hourStart, rxBytes, txBytes) - _ = dao.UpsertTrafficAggregateDaily(*peer.Id, dayStart, rxBytes, txBytes) } } func kickAccount(apiPort int64, trafficStatsSecret string) { diff --git a/apps/service/dashboard.go b/apps/service/dashboard.go index bcda1da..2b52e7b 100644 --- a/apps/service/dashboard.go +++ b/apps/service/dashboard.go @@ -46,28 +46,29 @@ func DashboardTimeseries(rangeKey string) (vo.DashboardTimeseriesVo, error) { fromMs := nowMs - int64(24*time.Hour/time.Millisecond) bucketMs := int64(5 * time.Minute / time.Millisecond) source := "sample" - r := strings.TrimSpace(rangeKey) - if r == "1h" { + r := "24h" + + switch strings.TrimSpace(rangeKey) { + case "1h": fromMs = nowMs - int64(time.Hour/time.Millisecond) bucketMs = int64(time.Minute / time.Millisecond) source = "sample" - } else if r == "7d" { + r = "1h" + case "7d": fromMs = nowMs - int64(7*24*time.Hour/time.Millisecond) bucketMs = int64(time.Hour / time.Millisecond) source = "hourly" - } else if r == "30d" { - fromMs = nowMs - int64(30*24*time.Hour/time.Millisecond) - bucketMs = int64(24 * time.Hour / time.Millisecond) - source = "daily" - r = "30d" - } else if r == "" { - r = "24h" + r = "7d" + case "24h", "": + fromMs = nowMs - int64(24*time.Hour/time.Millisecond) bucketMs = int64(5 * time.Minute / time.Millisecond) source = "sample" - } else { r = "24h" + default: + fromMs = nowMs - int64(24*time.Hour/time.Millisecond) bucketMs = int64(5 * time.Minute / time.Millisecond) source = "sample" + r = "24h" } traffic, err := dao.DashboardTrafficTimeseries(fromMs, nowMs, bucketMs, source) @@ -92,8 +93,6 @@ func DashboardTopPeers(rangeKey string, limit int) ([]vo.DashboardTopPeerVo, err fromMs := nowMs - int64(24*time.Hour/time.Millisecond) if strings.TrimSpace(rangeKey) == "7d" { fromMs = nowMs - int64(7*24*time.Hour/time.Millisecond) - } else if strings.TrimSpace(rangeKey) == "30d" { - fromMs = nowMs - int64(30*24*time.Hour/time.Millisecond) } return dao.DashboardTopPeers(fromMs, nowMs, limit) } diff --git a/apps/service/metrics_collector.go b/apps/service/metrics_collector.go index 900a5f9..91a0f5a 100644 --- a/apps/service/metrics_collector.go +++ b/apps/service/metrics_collector.go @@ -14,6 +14,7 @@ import ( ) const hysteriaVersionCacheTTL = 15 * time.Minute +const statsRetention = 7 * 24 * time.Hour var ansiRe = regexp.MustCompile(`\x1b\[[0-9;]*[A-Za-z]`) var hysteriaVersionRe = regexp.MustCompile(`(?i)v?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?`) @@ -150,9 +151,19 @@ func CollectMetricsSnapshot() { _ = dao.SaveMetricSample(metric) } -func CleanupMetricsRetention() { - cutoff := time.Now().Add(-72 * time.Hour).UnixMilli() - _ = dao.CleanupMetricSample(cutoff) +func CleanupStatsRetention() { + now := time.Now() + cutoffMs := now.Add(-statsRetention).UnixMilli() + + hourMs := int64(time.Hour / time.Millisecond) + dayMs := int64(24 * time.Hour / time.Millisecond) + cutoffHour := cutoffMs - (cutoffMs % hourMs) + cutoffDay := cutoffMs - (cutoffMs % dayMs) + + _ = dao.CleanupMetricSample(cutoffMs) + _ = dao.CleanupTrafficSample(cutoffMs) + _ = dao.CleanupTrafficAggregateHourly(cutoffHour) + _ = dao.CleanupTrafficAggregateDaily(cutoffDay) } func DashboardSnapshot() metricsSnapshot {