- 注册表:docs/architecture/README.md §2,37 份 canonical(frontmatter topic+canonical:true)与表双向机器对账
- 门:.agents/tools/docs-gate.py 六检(品牌根/canonical唯一/死链/入口卫生/留痕隔离/设计档申报),挂 .githooks/pre-commit(本仓已激活)+ .gitea/workflows/docs-gate.yml(待runner)+ wave-close 第8步;旧 check-deadlinks.sh 退役并入 G3
- 清缩:删 54 项历史档(plans 16/agent-specs 设计与spike 20/brainstorms 5/memorys 3/goals+作战清单完成史归档/王蓝莓design/SAA现状html/add-game-template);channel-spike 564K 代码资产迁仓级 spikes/;六件删前蒸馏已迁(代码评审16条open项→进度总账§5、prefix-cache字段表→cheap-model skill、意图基线29条→需求清单附录、九门降级rationale→验收门、A11 TODO→tech-decisions、3layer边界→littlejs-game-dev 指针)
- 修口径约90处:六处SAA『现行主线』旧标、Nacos/RocketMQ『未部署』旧述(07-01反转)、gameDefinition残留、全部死链改 git show 定位;AGENTS.md 249→136行(决策史归tech-decisions);_index 改纯在飞板;对外演示版 md→html
- 依据:docs/agent-specs/2026-07-02-文档治理-{全量普查与裁决-report,SoT注册表与治理门-设计}.md(四路普查191份md+Codex/Opus双评审必修项已折入);恢复基线 8ea97234(单档 git checkout 8ea97234 -- <路径>)
297 lines
42 KiB
Markdown
297 lines
42 KiB
Markdown
---
|
||
topic: 观测体系
|
||
canonical: true
|
||
date: 2026-06-21
|
||
---
|
||
|
||
# 运维域 · 线上观测体系设计
|
||
|
||
> 绘境AI 线上观测体系的 canonical 设计稿,回答线上服务跑起来之后靠什么持续看见它、靠什么在它出问题时被叫醒。它补的是运维主档 [README §4](README.md) 立位、但一直留白的那一块:主档 §1.3/§1.4 回答了"部署后跑一遍冒烟门确认健康"和"健康到 ≥99.5% 可用性才算达标",但"线上持续靠什么观测、5xx 飙升靠什么发现、生成失败率掉了谁告诉你"这一问,现行只有一个秒级冒烟门加一个可用性数字撑着,配不上一个要对外服务的平台。
|
||
> **给谁看**:搭观测栈和埋点的工程师、值守线上的人、做生成质量与成本对账的人、关心可用性达标证据的创始人。
|
||
> **边界**:本稿只管观测本身——采集怎么埋、看板告警怎么分工、admin 怎么进大盘。观测栈的部署落点与 k8s 迁移强相关:创始人 2026-06-21 已定本阶段上 k8s、观测栈随服务一起往 k8s 收(见 [k8s迁移.md](k8s迁移.md))。本稿按那份迁移档的目标形态设计——观测栈落在 mini-desktop 单节点 k3s 的 `observability` namespace;k3s 就绪前可先以 mini-desktop 裸 docker-compose 过渡。埋点产出标准 OTLP,与后端组件的部署方式在 OTLP 协议这个接口上解耦,所以"先 docker-compose 过渡、后随 k8s 收编"对应用侧埋点零改动。k8s 怎么迁、迁到什么形态属 k8s迁移.md,本稿不展开。
|
||
|
||
---
|
||
|
||
## 1. 现状:有一半客户端地基,但大半没接线、没后端
|
||
|
||
后端的观测地基处于"零件在、没装上"的状态,逐件核对如下,把"现在已经有什么"和"还得新建什么"分清楚,免得把蓝图当现状。
|
||
|
||
yudao 框架层有一个 `huijing-spring-boot-starter-monitor` starter,它里面的零件状态参差不齐:
|
||
|
||
- `TraceFilter`:**已实现、能用**。每个响应回写一个 `trace-id` 头(`TraceFilter.java`,header 名就是小写 `trace-id`,不是 `X-Trace-Id`)。但它取的 traceId 来自 SkyWalking 的 `TracerUtils.getTraceId()` → `TraceContext.traceId()`;SkyWalking agent 不在席时,这个值是占位串而非真实 traceId。这条是"trace_id 从入口注入"那条规范的落脚点,但要真出一个能串链路的 traceId,得先把它对齐到下面要新建的 OTel trace context。
|
||
- `@BizTrace` 注解 + `BizTraceAspect` 切面:**注解和切面类都在,但 AOP 当前被禁用**。`HuijingTracerAutoConfiguration` 里注册切面的 `@Bean`(`bizTracingAop()` / `tracer()`)是注释掉的(源码 line 28–40,带 `TODO 后续换 opentelemetry` 的注释),所以 `@BizTrace` 现在贴上去不会织入任何埋点。要用得先取消注释并验证 AOP 织入——但既然要换 OTel,更可能是直接用 OTel 的手动 span 取代它,而不是去启用这套绑 SkyWalking 的旧切面。
|
||
- `HuijingMetricsAutoConfiguration`:**类在,给指标打 `application=<服务名>` 公共标签**;`micrometer-registry-prometheus` 作为 `optional` 依赖带进了 starter。
|
||
- SkyWalking `apm-toolkit-*`(含 logback 集成)和 `spring-boot-admin-starter-client`:同样以 `optional` 依赖躺着,默认不启用。
|
||
|
||
关键的一条事实:**这个 monitor starter 没有进生成主线的部署单元**。线上跑的单体是 `huijing-server`(`HuijingServerApplication` 聚合 `game-module-aigc-server` 等十几个业务模块),它的 pom 里没有 `huijing-spring-boot-starter-monitor`(该 starter 只被 gateway/infra/pay/system/bpm 等模块引了)。所以 `TraceFilter`/`@BizTrace`/`HuijingMetricsAutoConfiguration` 这套地基,**对 aigc 这条生成主链路的运行进程而言,classpath 上根本没有**——要用,得先在 `huijing-server`(或 aigc-server)的 pom 里引入。
|
||
|
||
生成主线那一侧倒是真有一段已落地的观测信号:aigc-server 已经引入 `spring-ai-alibaba-graph-core` + `spring-ai-alibaba-starter-graph-observation`(SAA v1.1.2.2,见 aigc-server pom),SAA 裸图编排在 `ObservationRegistry` 非空时挂上 graph-core 自带的 `GraphObservationLifecycleListener`(生产代码 `SaaStudioGraph.build` 已接,`AigcExecutorConfiguration` 软取 Micrometer `ObservationRegistry`,缺则降级 NOOP),**每个图节点发一条 `spring.ai.alibaba.graph.node.<id>` 的 Micrometer observation,带 trace 和耗时,失败反映在指标里**(见 [`.agents/skills/saa-graph-orchestration.md`](../../../.agents/skills/saa-graph-orchestration.md) §5)。这是后端唯一一段已经在以 Micrometer 标准产出、且依赖已就位的观测信号——缺的只是一个把它收走的后端,以及一个非 NOOP 的 `ObservationRegistry`(后者要 Spring Boot actuator/micrometer 装配在席才有,而 actuator 也还没引)。**口径**:这段 SAA 节点 observation 是**已落地的遗留信号**——生成框架已于 2026-06-25 收敛到 AgentScope、SAA 降为最低优先级,所以它是现存 SAA 实现的观测地基,先按现状接进来、待生成主线迁到 AgentScope 后再按新框架重挂;观测栈与生成框架经 OTLP 在协议层解耦,这段信号的接入不受框架收敛影响,下文凡说"SAA 节点 observation"均按此理解。
|
||
|
||
前端那侧是另一种现状:studio 已经有业务遥测(性能 / 游玩 / 会话),事件经 `/app-api` 落进 `game_telemetry_event`,聚合成 `game_telemetry_game_stat`,再回灌游戏热度和质量分(见 [后端数据模型 §2.3](../后端/数据模型.md))。这条业务数据回路和"前端页面在真实用户浏览器里加载多慢、报了什么 JS 错"这种前端可观测性是两回事,后者现在完全没有。
|
||
|
||
缺口归纳成三条:
|
||
|
||
1. **没有任何遥测后端在收数据**。Micrometer 指标没人 scrape,trace 没地方落,日志还是各进程自己的文件。蓝图里画过的 Prometheus / Grafana / Jaeger 三个容器,MVP 现实从未起过(历史回收判定 运维基建-001)。
|
||
2. **采集标准不统一,且和创始人选定的不一致**。现状脚手架是 SkyWalking + Micrometer 两套各走各的;创始人 2026-06-21 定的是 **OpenTelemetry(OTel)一套统一 trace / metrics / log**。这不是补一个后端就完,而是要把采集标准收敛到 OTel。
|
||
3. **告警是一张纯文档表,没有一根通道真接上**。`security-and-reliability.md` §6 把 P0–P3 升级链和触发条件写全了(P1=5xx>2% 或生成成功率<70%),但飞书/钉钉 webhook 谁配、P0 电话怎么打,全是空头承诺(历史回收判定 运维基建-004)。预算里留了 ¥500/月给监控/备份,但这笔钱对应的能力一直是空的(运维基建-027)。
|
||
|
||
这份设计要做的,就是把这三条补成真东西:引入 OTel 统一采集、把已有的 SAA 图节点 observation 和后续新埋的指标接进去、给 Grafana + 夜莺喂上数据、把告警通道接通、并在 admin 开一个进大盘的入口。下面 §3 凡涉及新建的契约面(后端 pom 依赖、新增指标埋点、admin 路由与查询接口),会单列 contract-first 清单,讲清"现在没有、要新建什么"。
|
||
|
||
---
|
||
|
||
## 2. 设计目标
|
||
|
||
观测体系做成之后,要能回答四个层次的问题,且每一层都有人(或告警)在看:
|
||
|
||
- **基础设施层**:每台机器、每个进程的 CPU / 内存 / 磁盘 / GC,够不够、会不会 OOM、磁盘会不会涨满。
|
||
- **服务层**:后端各 API 的 QPS / 错误率 / P95 延迟,可用性够不够 ≥99.5%,达标用 error budget 说话而不是拍脑袋。
|
||
- **业务层**:生成成功率(≥80% 是验收线,也是最关键的业务健康指标)、生成 P50/P95 耗时、队列积压、广告/分账链路有没有断、生成成本有没有失控。
|
||
- **前端层**:真实用户那边首屏多慢(P75<3s 目标)、JS 报错率、关键交互(刷流、点生成)的成功率。
|
||
|
||
配套的硬目标:
|
||
|
||
- **采集统一**:trace / metrics / log 三件都经 OTel 一套标准产出,trace_id 从网关入口贯穿到 SAA 节点和 new-api 调用,一个 trace_id 能把"一句话生成游戏"这条链从前端点击串到模型返回。
|
||
- **关键告警必达**:可用性、错误率、生成失败率三类告警必须真能把人叫醒(不是只在看板上变红)。
|
||
- **admin 一键进盘**:运营和排查从后台点一下就进监控大盘,不用各记各的 Grafana 地址、各自登录。
|
||
- **埋点与部署解耦**:观测栈按 k8s迁移.md 落在 mini-desktop k3s 的 observability namespace,k3s 就绪前先 docker-compose 过渡(见 §4)。无论过渡形态还是 k3s 形态,后端那侧的埋点(OTel agent + 语义约定)一行不用改,只换观测组件的部署方式——埋点是应用内的事,观测后端是部署的事,两者在 OTLP 协议这个接口上对接。
|
||
|
||
---
|
||
|
||
## 3. 方案
|
||
|
||
### 3.1 整体形态:OTel 采集 + 三类后端 + Grafana/夜莺双看板
|
||
|
||
观测体系是一条"采集 → 管道 → 存储 → 看板/告警"的链。创始人点名的组件是 OTel(采集和管道)、Prometheus(存指标)、Grafana 和夜莺(Nightingale,在最上面分工做看板与告警);trace 后端和日志后端创始人没点具体哪个,本稿给倾向并标"选型待定"(见 §6)。整条链的形态如下。
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph SRC["采集侧(被观测的进程)"]
|
||
BE["huijing 后端单体<br/>OTel Java Agent 自动注入<br/>+ Micrometer 指标 + SAA 节点 observation"]
|
||
FE["game-studio / game-admin 前端<br/>OTel Web SDK(可选,后期)<br/>页面性能 / JS 错误 / 前端 trace"]
|
||
HOST["主机/中间件<br/>node-exporter · MySQL/Redis exporter"]
|
||
end
|
||
subgraph PIPE["管道:OTel Collector(统一入口)"]
|
||
COL["OTel Collector<br/>OTLP 收 trace/metrics/log<br/>批处理 / 脱敏 / 路由"]
|
||
end
|
||
subgraph STORE["存储后端(各管一类)"]
|
||
PROM["Prometheus<br/>指标时序"]
|
||
TRC["trace 后端<br/>Tempo / Jaeger(选型待定)"]
|
||
LOG["日志后端<br/>Loki 等(选型待定)"]
|
||
end
|
||
subgraph VIEW["看板与告警"]
|
||
GRAF["Grafana<br/>统一看板(trace/metrics/log 三联查)"]
|
||
N9E["夜莺 Nightingale<br/>告警规则引擎 + 通知分发<br/>P0–P3 升级链落地"]
|
||
end
|
||
ADMIN["game-admin 控制台<br/>观测入口 / 观测大图"]
|
||
|
||
BE -->|OTLP| COL
|
||
FE -->|OTLP/HTTP| COL
|
||
HOST -->|scrape| PROM
|
||
COL -->|metrics| PROM
|
||
COL -->|trace| TRC
|
||
COL -->|log| LOG
|
||
PROM --> GRAF
|
||
TRC --> GRAF
|
||
LOG --> GRAF
|
||
PROM -->|查询/拉取| N9E
|
||
N9E -->|webhook| NOTIFY["飞书 / 钉钉 / 短信 / 电话"]
|
||
ADMIN -->|嵌入 + SSO 免登| GRAF
|
||
ADMIN -.->|告警概览 API| N9E
|
||
```
|
||
|
||
几个选型决定要讲清为什么:
|
||
|
||
**为什么 OTel Collector 居中,而不是各组件直连后端。** 让每个被观测进程直接把数据推给各自的后端(指标推 Prometheus、trace 推 Jaeger),会把后端地址、协议、脱敏逻辑全硬编码进每个应用,上 k8s 或换后端就得改一圈。中间放一个 OTel Collector 当统一入口,应用只认一个 OTLP 端点,**脱敏、批处理、采样、路由全在 Collector 这一层做**——手机号/token 脱敏这条规范(`security-and-reliability.md` §6)就落在 Collector 的 processor 里集中执行,而不是指望每个埋点点各自记得脱敏。换后端、上 k8s 时,改 Collector 的导出配置即可,应用零改动。这正是"先单体可跑、后平滑上 k8s"能成立的技术支点。
|
||
|
||
**为什么后端用 OTel Java Agent,而不是继续用 SkyWalking toolkit。** 现状脚手架里那套 SkyWalking `apm-toolkit-*` 是 yudao 自带的,但它和 Micrometer 是两条平行的采集路,且不是创始人选定的标准。OTel 的 Java Agent 能**零代码自动织入** Spring MVC / JDBC / Redis / HTTP client 的 span,同时通过 OTel 的 Micrometer bridge 把现有的 Micrometer 指标(含已经在产出的 `spring.ai.alibaba.graph.node.*` 那批 SAA 节点 observation)一并收走。所以采用 OTel Agent = 自动 trace + 收编现有指标,**一步把两条平行路收敛成一条**;SkyWalking 那套 toolkit 退役为不启用(依赖留着不删,免得动 yudao 框架层,但 profile 里不开)。这是这份设计里唯一一个"用框架现成的 vs 换标准"的实质取舍,理由是创始人定了 OTel,且 OTel 能向后兼容地把 Micrometer 那部分一起带走,换的成本低、收益是采集口径统一。
|
||
|
||
**为什么是 Grafana 和夜莺两套,各管什么。** 这两个不是冗余,是分工:
|
||
|
||
- **Grafana = 看(read-only 的眼睛)**。它是统一看板层,把 Prometheus 的指标、trace 后端的链路、日志后端的日志接成数据源,做成大盘,支持"从一条慢请求的指标点进它的 trace、再点进这段时间的日志"这种三联下钻。admin 一键进的"监控大盘"就是 Grafana。
|
||
- **夜莺 Nightingale = 叫(会响的告警)**。夜莺是国产的告警规则引擎加值班/通知分发系统,中文生态、飞书钉钉接入顺手,正好补上"告警通道一根没接"这个最大的空。它从 Prometheus 拉指标算告警规则,把 `security-and-reliability.md` §6 那张 P0–P3 升级链表**变成真的规则和真的通知**(P0 电话、P1 短信+群、P2/P3 群)。
|
||
|
||
简言之 Grafana 负责"你主动去看时看得清",夜莺负责"你没在看时它把你叫来"。两者都从同一份 Prometheus 指标取数,口径一致。(注:Grafana 自带 alerting,夜莺也能做看板,功能上有重叠;这里按创始人选定的分工——Grafana 主看板、夜莺主告警——各取所长,不强行二选一。)
|
||
|
||
### 3.2 后端怎么埋:Agent 兜底 + 关键链路手动加 span
|
||
|
||
后端埋点分两层,自动的兜底广度、手动的补关键链路的深度。
|
||
|
||
**自动层 = OTel Java Agent。** 启动时挂一个 `-javaagent:opentelemetry-javaagent.jar`,配好 OTLP 端点和服务名,它自动给每个 HTTP 入口、每次 JDBC 查询、每次 Redis 调用、每次出网 HTTP(含调 new-api 的那次)生成 span 并串成 trace。这一层不改一行业务代码,就把"一个请求经过了哪些 SQL、哪些下游、各花多久"全画出来。
|
||
|
||
这里有一个必须解决的双 traceId 问题。现有的 `TraceFilter` 回写的响应头是 `trace-id`(小写),它的值来自 SkyWalking 的 `TracerUtils.getTraceId()`;而 OTel agent 走的是 W3C `traceparent` 标准、生成自己的 traceId。如果两套并存而不打通,响应头回的 `trace-id` 和 Grafana 里 OTel trace 的 traceId 会是两个不同的值,前端拿着 `trace-id` 去 Grafana 查不到对应链路。统一成一根的方向是:启用 OTel agent 后,把 `TraceFilter` 回写的来源从 SkyWalking 的 `TracerUtils` 换成 OTel 当前 span 的 traceId(`Span.current().getSpanContext().getTraceId()`),让响应头里的 `trace-id` 就是 OTel 的 traceId。这样前端报错时带回的 trace_id 能直接在 Grafana 里查到对应后端链路。具体改 `TraceFilter` 取数来源、还是用 OTel 的 baggage/响应头注入扩展,**待核**(见 §6 第一条)。
|
||
|
||
**手动层 = 给生成链路补结构化 span 和业务指标。** 自动 agent 看得见"调了 new-api 花了 8 秒",但看不见"这是生成的第几步、过了几道门、就绪分多少"——这些业务语义得手动埋。其中 SAA 图节点这一段地基已经在:每个节点已发 `spring.ai.alibaba.graph.node.<id>` observation(依赖已就位,见 §1),只要接上非 NOOP 的 ObservationRegistry,这些自动变成 trace 里的 span。但下面这几个**关键业务指标目前在代码里全部零命中,是要新建的埋点,不是已有数据**——它们需要在对应的 Worker / 控制平面类里补 `MeterRegistry`(或 OTel `Meter`)的计数/计时注册调用后才会有数据。各指标的设计口径(都打成 Micrometer/OTel metrics,带 `template`、`model`、`source` 维度标签):
|
||
|
||
- `gen_task_total{status}` —— 生成任务总数按终态分(对齐 `game_aigc_task.status`:2 成功 / 3 失败 / 4 超时 / 5 取消),**生成成功率 = success / (success+fail+timeout)**,作为 P1 告警(<70% 触发)和验收线(≥80%)的取数源。埋点位:任务终态回填处(`AigcTaskServiceImpl` / Worker 写终态那一步)。
|
||
- `gen_duration_seconds` —— 生成耗时分布(histogram),出 P50/P95,对齐"P50<60s、P95<180s"的硬指标。埋点位:Worker 一局生成的起止。
|
||
- `gen_queue_depth` —— 队列积压(全局在飞 = queued+running)。**取数口径要对齐控制平面的真实实现**:背压阈值是 `AigcControlPlaneProperties.queueDepthLimit`,代码里当前是占位值 **50**(注释明确"占位值,需确认",不是蓝图里画过的 500);超阈值时走业务码 `AIGC_BACKPRESSURE_REJECTED`(`1_101_001_002`),**HTTP 仍 200、body.code 非 0,不产生 HTTP 429/503**(见 [开闸验收门-W-G1](../架构/生成引擎/验收门.md) 决策E,以及 `ErrorCodeConstants` 注释)。所以这个指标的告警语义是"在飞数逼近 `queueDepthLimit`",不是"返回 429 的次数"。埋点位:控制平面 `enqueueWithControlPlane` 背压判定处。
|
||
- `gen_gate_fail_total{gate}` —— 九门各门失败计数,从 `game_aigc_task.trace_json`(九门轨迹账本)那条信息里出,定位是哪道门在拖低成功率。埋点位:九门校验节点。
|
||
- `llm_cost_cents` / `llm_cache_hit_rate` —— 生成成本与前缀缓存命中率。**成本数据源待薄片落地**:后端代码现在没有任何读取 new-api 计费日志(`logs.quota`)的逻辑——`logs.quota 权威对账`目前只是 `SaaGraphDispatcher` 里的一句注释和 旧 memorys 死库(已删,git 可查) 的一个待建薄片设想,不是已接通的链路。要把成本做成实时指标,得先落地一个读 new-api `logs.quota` 的薄片把成本拉出来,再注册成指标。**缓存命中率掉到 50% 以下要告警**(历史回收判定 运维基建-003 的成本早期哨兵,缓存因 few-shot 字节漂移失效会让成本翻几倍)。
|
||
|
||
> **contract-first(新建项清单)**:生成链路要接观测,跨模块面的新增物有三类——① **后端依赖**:`huijing-server`(或 aigc-server)pom 引入 OTel 相关依赖(actuator + micrometer + OTel Java Agent 走启动参数,不进 pom 也可),让 `ObservationRegistry` 非 NOOP;② **指标埋点**:上面五个指标在对应 Worker/控制平面/九门节点类补 `MeterRegistry` 注册调用(纯应用内新增,不动契约 yaml/DB);③ **成本薄片**:新建读 `logs.quota` 的成本采集薄片(单独一件事,见上)。这三类都是"现在没有、要新建",落地前观测大盘上的生成指标全是空的。
|
||
|
||
接好之后,生成这条最值钱的链路既有 trace(一次生成的完整时间轴 + 每个节点)、又有 metrics(成功率/耗时/积压/成本的趋势与告警),trace 和 metrics 经同一个 trace_id 关联。下面这张图把"一句话生成游戏"的 trace 贯穿画出来:
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
U["前端点击<br/>生成游戏"] -->|traceparent 注入| GW["网关入口<br/>TraceFilter 起 root span"]
|
||
GW --> AIGC["aigc 服务<br/>建 game_aigc_task"]
|
||
AIGC --> SAA["SAA 裸图编排<br/>每节点一条 observation span"]
|
||
SAA -->|node: brief| N1["..."]
|
||
SAA -->|node: gen_source| N2["调 new-api<br/>OTel agent 自动 span"]
|
||
N2 --> NAPI["new-api 网关 → 便宜 LLM"]
|
||
SAA -->|node: nine_gates| N3["九门校验<br/>gen_gate_fail 指标"]
|
||
SAA --> BUILD["build-from-source<br/>编译产物"]
|
||
AIGC -. "终态回填 status<br/>gen_task_total{status}" .-> METRIC[("指标:成功率/耗时/成本")]
|
||
|
||
style METRIC fill:#1a2b3c,color:#fff
|
||
```
|
||
|
||
一个落地约束要写在这里:**埋点开关默认关、经 profile 显式打开,失败绝不影响主流程**。OTel agent 和指标上报都不能因为 Collector 挂了就拖垮生成——agent 走异步批量上报、Collector 不可达时本地丢弃(对齐 SDK 降级铁律里 Telemetry 类"上报失败静默丢弃、稳定性>数据完整性"的精神,见 `security-and-reliability.md` §7)。这条保证了观测栈本身是旁路,挂了不咬主链路。
|
||
|
||
### 3.3 前端怎么埋:先收 JS 错误与首屏,trace 打通靠 traceparent
|
||
|
||
前端可观测性分两步走,因为它和已有的业务遥测要划清边界,别重复造。
|
||
|
||
业务遥测(谁玩了哪款、留存多少)继续走现有的 `/app-api/telemetry` → `game_telemetry_event` 那条,不动。**新增的是"前端运行健康"这一类**:页面首屏耗时(对齐 P75<3s)、JS 运行时报错、关键接口(刷流、生成、发布)的失败率。这部分用 OTel 的 Web SDK 采集,经 OTLP/HTTP 推给同一个 Collector。
|
||
|
||
更要紧的是把前后端 trace **连成一根**:前端发起后端请求时,在请求头注入 OTel 的 `traceparent`(W3C trace context 标准头),后端 agent 认这个头、把后端 span 挂到同一个 trace 下。这样一次"点生成 → 后端建任务 → SAA 跑图 → 调模型"的全过程是一个 trace,从用户浏览器一直串到模型返回。生成失败时,前端拿到的 trace_id 能在 Grafana 里直接查到这次生成卡在哪个节点、哪道门、调模型报了什么——这是排障效率的关键。
|
||
|
||
前端这块**排在后端之后做**:后端 + 基础设施的观测是 ≥99.5% 可用性达标的直接证据,优先级最高;前端运行健康是体验优化,价值真实但不卡可用性目标,放第二批(见 §4)。
|
||
|
||
### 3.4 告警:把文档表变成夜莺的规则和通道
|
||
|
||
告警是这份设计里"从无到有"最实的一块。`security-and-reliability.md` §6 那张 P0–P3 表现在是纯文档,夜莺要把它落成三样东西:**规则(什么条件触发)、分级(P0/P1/P2/P3)、通道(怎么通知、多久响应)**。逐级对应:
|
||
|
||
| 级别 | 触发条件(夜莺规则,取数自 Prometheus) | 通道 | 响应时限 |
|
||
|---|---|---|---|
|
||
| **P0** | 服务不可用(health 探测连续失败 / 整机宕)、数据丢失、安全事件 | 电话 + 短信 + 群 | 5 分钟 |
|
||
| **P1** | `5xx 占比 > 2%` 持续 N 分钟 / **生成成功率 < 70%** / 支付异常 | 短信 + 群 | 15 分钟 |
|
||
| **P2** | `API P95 > 800ms` / 在飞数逼近 `queueDepthLimit`(当前占位 50)/ 错误率上升 / **缓存命中率 < 50%** | 群通知 | 1 小时 |
|
||
| **P3** | 非核心模块降级 / 日志异常增长 / 磁盘水位 > 80% | 群通知 | 工作时间 |
|
||
|
||
三类创始人点名的关键告警都在表里有家:**可用性**走 P0(health 连续失败)、**错误率**走 P1(5xx>2%)、**生成失败率**走 P1(成功率<70%)。另外把两条历史回收清单里悬空的哨兵补进来:**缓存命中率<50%**(成本早期哨兵,运维基建-003)进 P2,**磁盘水位>80%**(运维基建-021,mini-desktop 上 staging+构建产物+jar 备份+批跑证据会涨满磁盘、满了 MySQL 直接挂)进 P3。
|
||
|
||
通道落地有一条务实的分期:**MVP 阶段先接飞书/钉钉群机器人 webhook 把 P0–P3 全打通**(这是零成本、当天能接的),P0 的"电话+短信"依赖短信网关/电话服务,**随真实化的支付/短信能力一起接**(现在 P0 先用群里 @所有人 + 短信兜底,电话留接口)。这条避免了"因为电话通道没接就说告警没做"——先把群通知接通,贵的通道按需补。
|
||
|
||
webhook 密钥(飞书/钉钉群机器人的 webhook URL 与签名 secret)按内网阶段铁律落进 [`docs/内网凭据与端点.md`](../../内网凭据与端点.md),和 `NEWAPI_KEY` 同处,**不走环境变量**——内网阶段地址和密钥统一进项目文档,夜莺配告警通道时从那份凭据档取。
|
||
|
||
### 3.5 admin 观测入口:从无到有的一整套(现状是零)
|
||
|
||
先讲现状:**这一块现在完全是空的,要整套新建**。`game-admin/src` 下没有任何观测/监控相关的路由、菜单或 Vue 组件(现有的 `infra/redis monitor` 是 yudao 自带的 Redis 监控,与本设计无关),后端也没有任何给 admin 用的观测查询接口。所以"控制台一键进监控大盘"不是接一根线,而是要补齐前端、后端、嵌入安全三件,缺一不可。
|
||
|
||
创始人要的入口落在 game-admin 上(Vue3 + Element Plus),做法是在控制台新建一个"观测"菜单,底下两块:
|
||
|
||
- **观测大图**:一个嵌入页,把 Grafana 的核心大盘(可用性 / 错误率 / 生成成功率 / 关键链路)以 iframe 或 Grafana 的 embed 方式嵌进 admin,运营点一下就看见全局健康,不用记 Grafana 地址。**注意 iframe 嵌入不是写个 `<iframe src>` 就完**:Grafana 默认带 `X-Frame-Options: deny`、且有自身的 CSP,浏览器会直接拒绝被 admin 页面嵌入。要让嵌入成立,得在 `grafana.ini` 里开 `[security] allow_embedding = true`(并按需放开 `cookie_samesite`、配 CSP `frame-ancestors` 允许 admin 源)。如果不想放开 Grafana 的嵌入限制,另一条路是不嵌 iframe、改由 admin 后端的观测查询接口(见下)直接取指标数据、admin 前端自渲核心曲线——避免跨源嵌入的安全开关,但要自己画图。两条选哪条见 §6。
|
||
- **跳转入口**:对需要深挖的场景(下钻某个 trace、查某段日志),提供直接跳转到 Grafana 对应面板的链接,在 Grafana 里做三联下钻。
|
||
|
||
这套入口要新建的三件,逐件列清(都是现在没有、要新建):
|
||
|
||
1. **后端管理员专属查询接口**:在 admin 侧后端(走 `system_users` 鉴权的 admin-api 段)加观测查询接口,带 yudao 的权限注解(`@PreAuthorize("@ss.hasPermission('observ:dashboard:query')")` 之类),用途有二——给"API 直渲"方案供数(读 Prometheus/夜莺接口聚合后回前端),以及给 SSO auth-proxy 做这层可信代理的落点。**接口受权限守门,不能让未授权 admin 用户读到观测数据,更不能把 Grafana/Prometheus 裸暴露出去**。
|
||
2. **admin 前端菜单 + 路由 + 组件**:在 admin 加"观测"一级菜单、对应路由,和观测大图/跳转入口两个视图组件。这部分前端 file 级细节(具体路由路径、组件文件、菜单挂载点)留在 admin 活代码里落,本稿只定形态。
|
||
3. **嵌入安全处理**:即上面 iframe 方案要处理的 `X-Frame-Options`/`allow_embedding`/CSP,或选 API 直渲彻底绕开嵌入。这件和第 1 件的"接口受权限守门"一起,构成观测入口的安全边界。
|
||
|
||
这里有个必须解决的体验问题:**别让运营进个监控还要再登一次 Grafana**。admin 用户走的是 yudao 原生的 `system_users` 身份(和 C 端 `game_player` 是两套人,见 [后端数据模型 §4](../后端/数据模型.md))。所以 admin → Grafana 要做**单点免登**。可选两条路,**具体选哪条待核**(见 §6):
|
||
|
||
1. **反向代理 + 请求头透传**:admin 后端做一层代理,把 admin 已登录用户的身份经可信请求头(Grafana 的 auth proxy 模式)透给 Grafana,Grafana 信任这个头直接放行。好处是 admin 和 Grafana 共用一套登录态,运营无感。
|
||
2. **Grafana 独立账号 + 嵌入只读**:Grafana 开匿名只读或共享只读账号,admin 嵌入的大盘走只读视图,深挖才跳独立登录。简单但体验差一截。
|
||
|
||
倾向第 1 条(auth proxy 透传),它最贴合"一键进盘、无二次登录"的要求;但要核 Grafana auth proxy 在嵌入(iframe)场景下的 cookie/同源限制,以及 admin 后端做这层代理的安全边界(别把 Grafana 整个暴露出去)。下面这张图画 admin 进盘的链路:
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
OPS["运营<br/>(system_users 已登录 admin)"] --> ADMIN["game-admin 控制台<br/>观测菜单"]
|
||
ADMIN -->|观测大图:嵌入只读大盘| EMBED["Grafana 嵌入面板<br/>(可用性/错误率/生成成功率)"]
|
||
ADMIN -->|深挖跳转| PROXY["admin 后端 auth-proxy<br/>透传 system_users 身份头"]
|
||
PROXY -->|可信头免登| GRAF["Grafana 完整大盘<br/>trace/metrics/log 三联下钻"]
|
||
ADMIN -.->|告警概览| N9E["夜莺告警列表<br/>(最近告警/值班状态)"]
|
||
EMBED --> GRAF
|
||
```
|
||
|
||
可以参考 yudao-cloud / vue-pro 已有的监控集成——它本身在"基础设施/监控中心"菜单下集成过 Spring Boot Admin、SkyWalking、Grafana 这类外部页面的嵌入,admin 侧的菜单挂载和嵌入方式可以直接借鉴(yudao 的具体集成形态**待核**,见 §6)。
|
||
|
||
### 3.6 与现有冒烟门、可用性目标怎么衔接
|
||
|
||
观测体系不是另起炉灶,它要和现有的两个东西接上,各管一段、不重叠。
|
||
|
||
**和冒烟门的关系 = 点检 vs 常态监控,互补。** `deploy/smoke-test.sh` 是**部署那一刻的就绪点检**(秒级、一次性、确认这次部署的关键 API 在岗),观测体系是**部署之后的常态监控**(7×24 持续、看趋势、出问题告警)。两者职责不重叠:冒烟门回答"这次部署有没有部坏",观测回答"部好之后跑得住不住"。衔接点在于——冒烟门可以把它那 12 项的结果也打成一条指标推给 Prometheus(部署成功/失败、各项耗时),这样"每次部署的健康度"也进了可观测的历史,而不是只在部署当时的终端里闪一下。
|
||
|
||
**和可用性目标的关系 = 观测是 ≥99.5% 的度量与举证手段。** 现在 ≥99.5% 是个目标数字,但没有任何东西在持续度量它、没有 error budget 在被消耗和记录。观测体系把它落地:用 health 探测的成功率算游戏流 API 的实际可用性,对着 `security-and-reliability.md` §5.1 那张 SLO 表(游戏流 99.5%/月 error budget 3.6 小时、AI 生成 99%/7.2 小时、支付 99.9%/43 分钟)做 burn rate 看板和告警。这样"达没达标"从一句承诺变成一张有数据、有 error budget 余量的看板,创始人随时能看见这个月还剩多少容错预算。
|
||
|
||
### 3.7 LLM 网关(new-api)健康巡检:盯生成命脉本身,而不是盯调它的那次请求(创始人 2026-06-22 历史回收判定捡回)
|
||
|
||
上面 §3.2 埋的 `gen_task_total`/`gen_duration_seconds` 这套指标,盯的是"业务侧调 new-api 这次调用快不快、成没成";它们看不见的是网关本身的健康——new-api 背后挂着多条上游通道,每条对应不同供应商的 key,一条通道的 key 失效或被供应商封了,落到业务侧只表现为"生成成功率掉了",但那已经是结果坏了之后。把网关自身的健康单拎出来盯,是因为它是整个平台的命脉:网关一旦多条通道批量失效,所有生成全停,而不是某一类游戏生成不了。这不是假想的风险——2026-06 真发生过二厂系通道整批作废,当时只能靠人去翻日志才发现生成为什么集体失败。
|
||
|
||
要盯的是三件,它们和生成成功率告警是互补的前后两层。**第一件是多通道健康巡检**:周期性地对 new-api 配置的每条上游通道做一次最小探活(一个极小的 chat completion 请求,只问通道还通不通、不在意内容),把每条通道的"通/不通、延迟"打成指标,这样看板上能直接看见"现在还有几条通道活着",而不是等业务调用失败了反推。**第二件是 key 激活状态监控**:盯每个 key 的有效性与额度,new-api admin 接口能查出 key 的启用状态和已用额度,key 被禁用或额度耗尽时要在它影响生成之前就告警。**第三件是批跑冻结阀**:当健康巡检判定可用通道掉到某个下限(比如只剩一条、或全废),要能自动把后台批量生成(W-G1 竞标批跑、夜间批生成这类高并发消耗 key 的任务)冻结住,避免在通道已经半废的情况下继续猛打、把仅存的通道也打爆,同时给前台单次生成留一条降级到单通道运行的活路。冻结阀拉起后告警必达,由人确认通道恢复后再解冻。
|
||
|
||
这三件的告警分层接进 §3.4 夜莺那张表:**单条通道失效、key 额度告警**属于"结果还没坏、但前哨亮了"的前置预警(归 P2 一档,先在群里通知去补通道/换 key);**可用通道全废、批跑冻结阀拉起**属于命脉级,生成即将或已经全停(归 P1,等同生成成功率<70% 的紧急级,短信+群叫人)。次序很清楚:通道健康巡检在前(结果坏之前的前哨),生成成功率<70% 告警在后(结果已经坏了),两层都要,缺前哨就只能等生成集体失败了才知道网关出了事。
|
||
|
||
> **巡检的部署落点**:网关健康巡检是一个轻量周期任务(每条通道探活 + 查 key 状态),它的运维归属并入下面 README §5 讲的"平台后台 job 调度面"——和结算 job、telemetry 聚合 job 一样,作为一个定时 job 跑在 staging 机上,失败/冻结阀触发的告警接进夜莺。探活产出的通道健康、key 额度指标推给 Prometheus,在 Grafana 上和生成成功率画在同一块大盘,让"网关背后还活着几条通道"和"生成成功率"并排可见。
|
||
|
||
> **contract-first(待落地,现在没有)**:① **巡检 job**:新建一个 new-api 网关健康巡检 job(周期探活每条通道 + 查 key 激活/额度),在后台 job 调度面注册;它读 new-api 的 channel/key 管理接口(端点与 admin token 按内网铁律取自 [`docs/内网凭据与端点.md`](../../内网凭据与端点.md))。② **新增指标**:`llm_channel_up{channel}`(每条通道通/不通)、`llm_channel_latency_ms{channel}`(探活延迟)、`llm_key_quota_remaining{key}`(key 剩余额度)——三者都是纯应用内新增的 Micrometer/OTel 指标,不动契约 yaml/DB。③ **冻结阀开关**:批跑侧需要一个可被巡检 job 置位的"生成批跑冻结"标志(一个 feature-flag 形态的开关,通道全废时置位、人工确认恢复后清),批跑任务启动前先读它;具体落成配置项还是控制平面状态待落地时定。这三件落地前,网关健康在看板上是空的,通道批量失效仍只能靠人翻日志发现。
|
||
|
||
---
|
||
|
||
## 4. 分期落地
|
||
|
||
创始人定的范围是"全做",但全做不等于一把上,要按"先撑住可用性达标、再优化体验、最后跟 k8s 收编"的依赖顺序排。
|
||
|
||
观测栈的落点跟着 [k8s迁移.md](k8s迁移.md) 走,统一口径:**目标形态是观测栈作为 mini-desktop 单节点 k3s 的 `observability` namespace workload 部署**(Collector/Prometheus/Grafana/夜莺四件,与被观测的 `huijing-staging` 同集群、各自 namespace)。**k3s 就绪前,可先在 mini-desktop 上以裸 docker-compose 把这套栈跑起来过渡**——k8s迁移.md 已明确"观测栈在裸 docker-compose 上也能跑",过渡形态和目标形态对应用侧埋点零差异(都是 OTLP)。这里有一条硬约束要写明:**观测栈不落 mini-infra**。mini-infra 是跨项目共享基建机(new-api/PostgreSQL/MinIO/Gitea 等 8 个常驻容器),free 仅约 569Mi,k8s迁移.md 定了"mini-infra 的共享基建一律不进集群、也不当 k8s 节点";把 Prometheus 这种吃内存的时序库塞进去会和 new-api/gitea 抢内存,违背创始人本阶段上 k8s 的裁定。所以观测栈和被观测的 staging 同机(mini-desktop),靠 k8s 的 requests/limits 隔离,而不是塞去 mini-infra。
|
||
|
||
**第一期:后端 + 基础设施观测,把可用性和生成失败率看见、告警接通。** 这是优先级最高的一期,因为它直接产出 ≥99.5% 可用性的度量证据和最关键的生成失败率告警。内容:在 mini-desktop 上起 OTel Collector + Prometheus + Grafana + 夜莺(k3s 的 observability namespace,或 k3s 就绪前先 docker-compose 过渡);后端挂 OTel Java Agent、引入 actuator/micrometer 让 `ObservationRegistry` 非 NOOP、接已有的 SAA 节点 observation、新埋生成链路的业务指标(成功率/耗时/积压/九门;成本指标待薄片落地后补);夜莺把 P0–P3 规则和飞书/钉钉群通道接通;主机/中间件挂 node-exporter 和 MySQL/Redis exporter。**依赖**:mini-desktop 上的部署资源;成本指标这一项额外依赖 new-api `logs.quota` 采集薄片(尚未落地,见 §3.2)。完成判据:Grafana 上能看见可用性、5xx 率、生成成功率三张核心图,夜莺能把一条真实告警打到群里。
|
||
|
||
**第二期:admin 观测入口 + 告警通道补全。** 在 admin 控制台加观测菜单,嵌入 Grafana 大盘、做 SSO 免登跳转;把 P0 的电话/短信通道随真实化能力补上。**依赖**:第一期的 Grafana 大盘已就绪;SSO 方案(§6 待核)定了再做;短信/电话通道依赖支付/短信能力真实化。
|
||
|
||
**第三期:前端可观测性。** 接 OTel Web SDK 收前端首屏/JS 错误,打通前后端 traceparent。**依赖**:第一期的 Collector 已就绪;价值是体验优化,不卡可用性,故排最后。
|
||
|
||
**与 k8s 的衔接关系**:上面三期的应用侧埋点不依赖具体部署形态。观测栈本身按 k8s迁移.md 的目标落在 mini-desktop k3s 的 observability namespace;k3s 就绪前先 docker-compose 过渡。从过渡形态收编到 k3s workload 时,后端 agent 的 OTLP 端点从 docker-compose 的 Collector 地址改指向集群内的 Collector Service——**应用侧埋点一行不改**,因为埋点产出的是标准 OTLP,对接点是协议不是部署。这是 §2 那条"埋点是应用内的事、后端是部署的事"目标的兑现方式。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
P1["第一期<br/>后端+基建观测<br/>可用性/生成失败率告警"] --> P2["第二期<br/>admin 入口 + 告警通道补全"]
|
||
P1 --> P3["第三期<br/>前端可观测性"]
|
||
P1 -.->|docker-compose 过渡→k3s workload 收编<br/>埋点零改| K8S["k8s 迁移<br/>(另一份设计)"]
|
||
P2 -.-> K8S
|
||
P3 -.-> K8S
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 验收与风险
|
||
|
||
### 5.1 怎么算做对了
|
||
|
||
按层给可验证的判据,每条都要能真跑出来、不是文档承诺:
|
||
|
||
- **采集统一可验**:发起一次"一句话生成游戏",在 Grafana 里用同一个 trace_id 能查到从网关入口 → SAA 各节点 → new-api 调用的完整 trace,且这条 trace 的 trace_id 等于响应头回写的 `trace-id`。
|
||
- **生成失败率可见可告警**:Grafana 有生成成功率实时图(对齐 `game_aigc_task` 终态口径);人为造一批失败把成功率压到 70% 以下,夜莺能在 15 分钟内把 P1 告警打到群里。
|
||
- **可用性可度量**:Grafana 有游戏流 API 可用性 + error budget 燃尽图,数字对得上 health 探测的实际成功率。
|
||
- **admin 一键进盘**:运营在 admin 控制台点观测菜单,不二次登录就看见核心大盘(SSO 免登真生效)。
|
||
- **告警通道真通**:P0–P3 各造一条触发,飞书/钉钉群真收到对应分级的通知。
|
||
- **旁路不咬主链**:把 Collector 停掉,生成主链路和各 API 行为不变(埋点失败静默丢弃),冒烟门仍全绿。
|
||
|
||
最后一条是底线验收:**观测栈本身挂掉,绝不能影响被观测的服务**。
|
||
|
||
### 5.2 风险
|
||
|
||
- **观测栈反噬主链路(最该防的)**。埋点同步化、上报阻塞、agent 拖慢启动,都可能让"看健康的东西"自己变成故障源。对策是 agent 异步批量上报、Collector 不可达时本地丢弃、埋点开关默认关经 profile 显式开、并把"停 Collector 后主链路不变 + 冒烟门全绿"列为硬验收。这条优先级最高,因为它直接威胁 ≥99.5% 可用性。
|
||
- **同机资源挤兑**。观测栈和被观测的 staging 同在 mini-desktop(huijing 单体 + studio + admin + MySQL + Redis 已共存约 15G),再加 Collector/Prometheus/Grafana/夜莺会进一步吃内存。这正是落 k3s observability namespace 的用意:靠 k8s 的 requests/limits + QoS 分级给观测栈设内存上限,别让 Prometheus 的时序库按宿主内存自取吃垮同机的 live 后端(对齐 k8s迁移.md 用 requests/limits 解决多服务共存零保护那条,以及历史回收清单 OOM 优先级保护/容器内存硬限,运维基建-019/020)。k3s 就绪前的 docker-compose 过渡期,等价手段是给每个观测容器设 `mem_limit`。**不放 mini-infra**的理由见 §4(它是共享基建机、free 仅约 569Mi、k8s迁移.md 定了绝不进集群)。
|
||
- **SkyWalking 与 OTel 并存期的双采集**。收敛到 OTel 的过程中,如果 SkyWalking toolkit 没真正关掉,会出现两套 trace 各采一遍、对不上号。对策是切 OTel 时在 profile 里显式禁用 SkyWalking 那套(`huijing.tracer` 相关开关关),依赖留着不删(不动 yudao 框架层)但运行时不启用,确保只有一条采集路在跑。
|
||
- **告警风暴与噪声**。规则配太敏感会一惊一乍、配太松会漏报,P0 通道(电话/短信)尤其不能被噪声打爆。对策是给每条规则配持续时间窗(`for: N 分钟`)和静默/聚合策略,先在 staging 跑一段观察阈值合不合适再上严格通道。
|
||
- **脱敏没在 Collector 兜住**。trace 和日志里可能带手机号/token,如果指望每个埋点点各自脱敏一定会漏。对策是把脱敏作为 Collector 的强制 processor 集中做,作为"任何数据进存储前的最后一道",对齐 `security-and-reliability.md` §6 的脱敏红线。
|
||
- **trace context 跨边界断裂**。前端 `traceparent`、yudao `trace-id` 头、OTel W3C 标准三者如果没对齐,trace 会在前后端边界或网关处断成两截,排障时串不起来。这是 §6 第一条待核,落地第一期就要先打通这根。
|
||
|
||
---
|
||
|
||
## 6. 待核与开放问题
|
||
|
||
下面几条是设计里现在没有十足把握、需要落地时核实或创始人拍板的,逐条列清,不臆造:
|
||
|
||
- **trace context 头怎么对齐**:OTel 用 W3C `traceparent`,yudao `TraceFilter` 回写的是自定义 `trace-id` 头,SkyWalking 又是另一套。三者怎么统一成一根 trace_id(让前端拿到的、响应头回的、Grafana 里查的是同一个),需要在第一期落地时按 OTel agent 的实际行为核实并打通。**待核**。
|
||
- **trace 后端与日志后端选型**:创始人点了 OTel + Prometheus + Grafana + 夜莺,但 trace 后端和日志后端这两个都没点具体哪个,同属选型待定。trace 后端候选 Tempo / Jaeger,**倾向 Tempo**(和 Grafana/Prometheus 同体系、三联下钻无缝、运维一套),需确认资源占用和夜莺侧是否需要 trace 数据;日志后端候选 Loki 等,**倾向 Loki**(同属 Grafana 栈),但和 trace 后端一样属创始人未点名,落地前定。**待核/待拍**。
|
||
- **admin 观测入口的嵌入方式与 SSO**:两个待定。① 嵌入方式——iframe 嵌 Grafana(要开 `grafana.ini` 的 `allow_embedding` + 放 CSP `frame-ancestors`、`X-Frame-Options`)还是 admin 后端查询接口取数、前端自渲(绕开嵌入安全开关但要自己画图),见 §3.5;② SSO——§3.5 列了 auth-proxy 透传(倾向)和独立账号两条路,前者体验好但要核 Grafana auth proxy 在 iframe 嵌入下的 cookie/同源限制和 admin 代理层的安全边界。两者都**待核**。
|
||
- **yudao-cloud / vue-pro 的监控集成具体长什么样**:创始人让参考它省搭建工,但它具体集成了哪些(Spring Boot Admin?Grafana 嵌入?自带 Prometheus 配置?)需要实际查证 yudao 的 monitor 模块和前端监控菜单再决定借鉴哪部分,别假设。**待核**。
|
||
- **夜莺和 Grafana alerting 的边界**:两者都能告警,本设计按"Grafana 主看板、夜莺主告警"分工,但如果夜莺接 Prometheus 数据源有适配成本,是否退而用 Grafana 自带 alerting 顶一部分,需落地时权衡。**待核**。
|
||
- **观测数据保留期与成本**:`security-and-reliability.md` §6 定了日志 ERROR/WARN 90 天、INFO 30 天;trace 和 metrics 的保留期没定。trace 数据量大,trace 后端存多久、Prometheus 指标存多久,直接影响 mini-desktop 的磁盘(75G)和那笔 ¥500/月监控预算够不够。**待拍**(创始人对一下账:预算里留的 ¥500/月监控冗余,够不够这套栈的存储)。
|
||
- **生成成功率告警阈值用 70% 还是别的**:`security-and-reliability.md` §6 写的 P1 是"生成成功率<70%",但验收线是 ≥80%。70% 是"已经很糟该紧急处理"的线,80% 是"达标线"。是否要在 70%(P1 紧急)之外再加一条 80%(P2/趋势预警),让成功率从 80% 往下掉时就先有预警而不是等到 70%,**待拍**。
|