sun
|
1e2be0cd5b
|
fix(telemetry): 指标写入对空接收者安全,修 nil 解引用 panic
metrics 包的全局指标(UpstreamTotal 等)默认是 nil,只有 main 调过 metrics.Init() 之后才有值。任何不经过 main 的调用路径都会在 controller/tts.go -> adapter/volcano/synthesis.go -> metrics.AdapterRecorder 处 nil 解引用,整个进程崩掉。
生产路径本来没问题(二进制一定先 Init),但这类崩溃只在运行时暴露,且漏掉指标初始化属于很容易踩的装配错误,不该以 panic 收场。
改动: Counter.Add / Gauge.Set / Gauge.Add / Histogram.Observe 增加空接收者判断,nil 时静默忽略(与 noop 语义一致);在包注释里写成显式设计约定,避免以后被当成冗余代码删掉。
|
2026-10-03 16:13:47 +08:00 |
|
sun
|
51bd7ae37a
|
fix(privacy): speaker ID 不再裸奔(3 处)
speaker 是火山复刻音色 ID,用户付费资产,不能裸奔。
本次修复 3 处泄漏:
1. controller/tts.go: /metrics label 用 sha1(speaker)[:8] 替代
- /metrics 无鉴权,Prometheus 可枚举,原值直接暴露是最大的泄漏面
- 哈希替代保留 per-voice 聚合能力,反推不出原值
- Admin UI 想看原名通过 /api/voices 拿 name 字段
2. setting/config.go: 启动日志 LogStartupSummary 用 MaskSpeaker
- API Key 早用 maskAPIKey,speaker 漏了
- 现在 S_G8tEKnaJ1 形式
3. adapter/volcano/synthesis.go: 合成 debug + 成功日志用 MaskSpeaker
- 之前 resource_id=xxx speaker=原始ID 直接打
- 现在打码
新增 telemetry/labels.go:
- SpeakerLabel(s) -> sha1(s)[:8] (8 字符十六进制,稳定、不可逆、同输入同输出)
- MaskSpeaker(s) -> 前 4 + **** + 后 4 (空串返中文未设置,长度 <=4 全打码)
- 空 speaker label -> 'unknown' (Prometheus 禁止空 label)
单测 telemetry/labels_test.go 覆盖:
- SpeakerLabel: 同输入同输出 / 不同输入不同输出 / 空串 unknown / 长度 8 / 全是 hex
- MaskSpeaker: 各种长度边界 + 真实火山 ID 形式
e2e 验证(本机):
- 启动日志看到打码形式,无明文
- 自动化 grep 原始 ID 在 server log: 0 匹配
- go test ./... 全绿
未 push(用户要求先修后等 M2 一起发)
|
2026-08-29 21:42:57 +08:00 |
|