From 72962beb0f97d83e2daf232b349cbed2903e210a Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 19 Jul 2026 19:20:59 +0800 Subject: [PATCH] feat(rate-limits): use 1m buckets and 24h/3d ranges Allow overview bucket_minutes=1; rate-limit analysis uses 1-minute buckets and replaces 7d preset with 3 days. --- docs/changelog/index.md | 2 +- .../app/(main)/access-logs/components/access-log-utils.ts | 6 +++--- .../(main)/rate-limits/components/rate-pressure-chart.tsx | 8 ++++---- frontend/app/(main)/rate-limits/page.tsx | 4 ++-- .../apps/openflare/observability/access_log_logics.go | 2 +- internal/apps/openflare/observability/routers.go | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/changelog/index.md b/docs/changelog/index.md index 7a94fc3c..9bb7c842 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -30,7 +30,7 @@ sidebar: false - 站点流量限制语义调整为空或 `0` 继承全局默认、`-1` 关闭、大于 `0` 自定义;修改全局默认后需发布配置版本生效。 - Agent Docker 部署命令默认挂载命名卷 `openflare-agent-pages` 持久化 Pages 目录,重建容器时无需重新拉取静态站点包。 -- 限流页新增「分析」视图:默认展示近 24 小时请求压力(RPS)与独立访客双轴趋势(5 分钟桶),支持域名过滤与 24 小时/7 天预设,并按窗口平均 RPS 排行域名与 IP;原全局默认配置迁入「配置」页签。 +- 限流页新增「分析」视图:默认展示近 24 小时请求压力(RPS)与独立访客双轴趋势(1 分钟桶),支持域名过滤与 24 小时/3 天预设,并按窗口平均 RPS 排行域名与 IP;原全局默认配置迁入「配置」页签。 ## [v3.4.1] - 2026-07-19 diff --git a/frontend/app/(main)/access-logs/components/access-log-utils.ts b/frontend/app/(main)/access-logs/components/access-log-utils.ts index 52fd4ba4..9d3b4e5a 100644 --- a/frontend/app/(main)/access-logs/components/access-log-utils.ts +++ b/frontend/app/(main)/access-logs/components/access-log-utils.ts @@ -9,8 +9,8 @@ export type SearchDraft = { export type OverviewRangeHours = 24 | 168 | 360 | 720; -/** 限流分析等短窗口场景:仅 24 小时 / 7 天 */ -export type RateLimitRangeHours = 24 | 168; +/** 限流分析等短窗口场景:仅 24 小时 / 3 天 */ +export type RateLimitRangeHours = 24 | 72; export const PAGE_SIZE_OPTIONS = [20, 50, 100, 200]; @@ -29,7 +29,7 @@ export const RATE_LIMIT_RANGE_OPTIONS: { label: string; }[] = [ { value: 24, label: '24 小时' }, - { value: 168, label: '7 天' }, + { value: 72, label: '3 天' }, ]; export const DETAIL_SORT_OPTIONS = [ diff --git a/frontend/app/(main)/rate-limits/components/rate-pressure-chart.tsx b/frontend/app/(main)/rate-limits/components/rate-pressure-chart.tsx index b44bcf2c..1588418a 100644 --- a/frontend/app/(main)/rate-limits/components/rate-pressure-chart.tsx +++ b/frontend/app/(main)/rate-limits/components/rate-pressure-chart.tsx @@ -11,10 +11,10 @@ import { calculateNiceAxisMax, formatCompactNumber } from '@/lib/utils/metrics'; import { formatOverviewTrendLabel, - type OverviewRangeHours, + type RateLimitRangeHours, } from '../../access-logs/components/access-log-utils'; -const DEFAULT_BUCKET_SECONDS = 300; +const DEFAULT_BUCKET_SECONDS = 60; const RPS_COLOR = '#38bdf8'; const VISITS_COLOR = '#a78bfa'; @@ -54,14 +54,14 @@ function formatRps(value: number) { type RatePressureChartProps = { data?: AccessLogOverview; - hours: OverviewRangeHours; + hours: RateLimitRangeHours; }; export function RatePressureChart({ data, hours }: RatePressureChartProps) { const bucketSeconds = (data?.bucket_minutes && data.bucket_minutes > 0 ? data.bucket_minutes - : 5) * 60 || DEFAULT_BUCKET_SECONDS; + : 1) * 60 || DEFAULT_BUCKET_SECONDS; const rangeLabel = useMemo(() => { const end = data?.generated_at ? new Date(data.generated_at) : new Date(); diff --git a/frontend/app/(main)/rate-limits/page.tsx b/frontend/app/(main)/rate-limits/page.tsx index d821d93e..6ecae144 100644 --- a/frontend/app/(main)/rate-limits/page.tsx +++ b/frontend/app/(main)/rate-limits/page.tsx @@ -31,12 +31,12 @@ function RateLimitsPageContent() { const [hosts, setHosts] = useState([]); const overviewQuery = useQuery({ - queryKey: ['openflare', 'rate-limits', 'overview', hours, hosts, 5], + queryKey: ['openflare', 'rate-limits', 'overview', hours, hosts, 1], queryFn: () => AccessLogService.getOverview({ hours, hosts: hosts.length > 0 ? hosts : undefined, - bucket_minutes: 5, + bucket_minutes: 1, }), enabled: !!user?.is_admin && tab === 'analysis', }); diff --git a/internal/apps/openflare/observability/access_log_logics.go b/internal/apps/openflare/observability/access_log_logics.go index 35eb195e..59cd3b04 100644 --- a/internal/apps/openflare/observability/access_log_logics.go +++ b/internal/apps/openflare/observability/access_log_logics.go @@ -374,7 +374,7 @@ func normalizeAccessLogOverviewQuery(input AccessLogOverviewQuery) AccessLogOver func normalizeAccessLogOverviewBucketMinutes(value int) int { switch value { - case 5, 60: + case 1, 5, 60: return value default: return defaultAccessLogOverviewBucketMinutes diff --git a/internal/apps/openflare/observability/routers.go b/internal/apps/openflare/observability/routers.go index 5f6116a8..2cb08356 100644 --- a/internal/apps/openflare/observability/routers.go +++ b/internal/apps/openflare/observability/routers.go @@ -22,7 +22,7 @@ import ( // @Param host query string false "请求 Host(单域名)" // @Param hosts query []string false "请求 Host 列表(多域名精确匹配)" // @Param hours query int false "统计时间范围(小时)" -// @Param bucket_minutes query int false "趋势桶分钟数(5 或 60,默认 60)" +// @Param bucket_minutes query int false "趋势桶分钟数(1、5 或 60,默认 60)" // @Success 200 {object} response.Any{data=observability.AccessLogOverview} "访问日志概览" // @Failure 400 {object} response.Any "参数错误" // @Failure 401 {object} response.Any "未登录"