refactor(analysis): 去掉排行 10/30/50 选择器,改为一次取 50 + 前端分页;零点结算昨天
=== 1. 为什么去掉「显示条数」选择器 === topk 的 N 不影响查询成本(扫描的 chunk 集合完全相同),实测: topk(10) 17833ms / 11 条 topk(30) 18019ms / 34 条 topk(50) 7394ms / 54 条 topk(100) 17553ms / 74 条 波动来自集群负载,与 N 无关 —— 它只决定最后返回多少序列。 所以"选 30"既不更快也不更慢,本质是个翻页开关; 而选它还要重新等一次十几秒的查询,纯亏。 改为:一次 topk(50),前端 10 条/页 → 5 页只需 1 次查询。 附带收益:占比的分母从"前 10 合计"变成"前 50 合计",更接近真实占比。 副标题明确写清"一次取前 50 个应用(占比按这 50 个合计计算)"。 === 2. 零点结算昨天(daily volume)=== 原来只有 30 分钟 ticker 回补,且启动时间不对齐整点 → 昨天最早的一段可能已经超出 Loki 24h 保留期被删, 结算结果系统性偏低,图上却标"完整一天",属静默错数。 新增 nextMidnightFinalize():每天 00:01 触发 FinalizeYesterdayVolume() - 昨天定稿 partial=false - 补一次条数(index/stats,一天一次可接受) - 顺带刷新今天 partial=true 的柱子 ticker 仍保留,负责当天数据的 30 分钟刷新。 === 3. 顺带 === - 去掉每日量"其中 N 天平台没有留存记录"的提示文案(按用户要求) - 修 QuickQueryTemplates.tsx 的未使用变量导致 tsc -b 失败 - 工作区里上一轮中断的"排行体积列"改动一并纳入(app-ranking 返回 bytes, TopAppsTable 增加体积列,快照记录 per-app 字节数) Pod = Hub latest = a16978d2f88b
This commit is contained in:
1 parent
63dd491c5b
commit
d4422f1541
22 files changed
+715
-117
No files matched your search
@@ -48,11 +48,19 @@ export const logsApi = {
|
||||
'/logs/stats', data, { timeout: 25000, ...opts }),
|
||||
/** 日志量统计:后端有 7 天范围上限与 30s 超时,前端超时略大于它 */
|
||||
/** 应用排行(长范围读平台预聚合快照,毫秒级,不扫日志内容) */
|
||||
appRanking: (sourceId: number, from: number, to: number, limit = 10, opts?: { signal?: AbortSignal }) =>
|
||||
http.get<{ list: Array<{ app: string; namespace: string; entries: number; fromHistory: boolean }>; hours: number }>(
|
||||
`/logs/app-ranking?sourceId=${sourceId}&from=${from}&to=${to}&limit=${limit}`,
|
||||
opts,
|
||||
),
|
||||
appRanking: (sourceId: number, from: number, to: number, limit = 10, opts?: { signal?: AbortSignal; sort?: 'bytes' | 'entries' }) => {
|
||||
const { signal, sort = 'bytes' } = opts ?? {}
|
||||
return http.get<{
|
||||
list: Array<{ app: string; namespace: string; entries: number; bytes: number; fromHistory: boolean }>
|
||||
/** 快照覆盖的小时数 */
|
||||
hours: number
|
||||
/** 其中带体积的小时数(体积列是本轮新增,早期快照只有条数) */
|
||||
bytesHours: number
|
||||
}>(
|
||||
`/logs/app-ranking?sourceId=${sourceId}&from=${from}&to=${to}&limit=${limit}&sort=${sort}`,
|
||||
signal ? { signal } : undefined,
|
||||
)
|
||||
},
|
||||
|
||||
/** 每日日志量历史(读平台库,毫秒级) */
|
||||
dailyVolume: (sourceId: number, days: number, opts?: { signal?: AbortSignal }) =>
|
||||
@@ -63,6 +71,19 @@ export const logsApi = {
|
||||
metrics: (data: MetricQuery, opts?: { signal?: AbortSignal }) => http.post<MetricSeries[]>('/logs/metrics', data, { timeout: 125000, ...opts }),
|
||||
labels: (sourceId: number, start?: number, end?: number) => http.get<string[]>(`/logs/labels${buildQuery({ sourceId, start, end } as { page?: number; pageSize?: number })}`),
|
||||
labelValues: (sourceId: number, name: string, query = '', start?: number, end?: number) => http.get<string[]>(`/logs/label/${encodeURIComponent(name)}/values${buildQuery({ sourceId, query, start, end } as { page?: number; pageSize?: number })}`),
|
||||
/**
|
||||
* 批量取多个 label 的候选值:`/logs/label-values?names=app,service_name,container&query={...}`
|
||||
*
|
||||
* 快捷查询的 app 下拉要做 app → service_name → container 三级回退,
|
||||
* 逐个请求要 3 个往返(每个都经 K8s API 代理到 Loki 索引);
|
||||
* 批量接口后端内部并发,一次往返拿全,前端只看"有没有值"。
|
||||
* 返回里缺某个 label 或取失败 = 空数组(不会抛错)。
|
||||
*/
|
||||
labelValuesBatch: (sourceId: number, names: string[], query = '', start?: number, end?: number, opts?: { signal?: AbortSignal }) =>
|
||||
http.get<Record<string, string[]>>(
|
||||
`/logs/label-values${buildQuery({ sourceId, names: names.join(','), query, start, end } as { page?: number; pageSize?: number })}`,
|
||||
opts,
|
||||
),
|
||||
/** 当前用户在某数据源上的授权范围(策略 labels;管理员 unrestricted=true) */
|
||||
myScope: (sourceId: number) => http.get<{ labels: Record<string, string>; unrestricted: boolean }>(`/logs/my-scope?sourceId=${sourceId}`),
|
||||
policyGroups: () => http.get<LogPolicyGroup[]>('/logs/policy-groups'),
|
||||
|
||||
Reference in new issue
Block a user