fix(gateway): 日志页脱敏改用「可带上限」变体(4096),摘要侧仍是 80
塔 2026-10-26 复审裁定:复用 trace.RedactText 让面板日志页每条 msg 都被切到 80 rune,是实质性 UX 回归(日志页就是排障面)。修法不是网关侧另写脱敏,而是 在 trace 包给上限加一个参数。 - trace/redact.go:新增导出 `RedactTextLimited(s, limit)`,语义 = 同一套凭据形状 清洗 + 按调用方给的上限截断;`RedactText` 改为它的 `maxSummaryRunes`(80) 调用形态,既有调用方零改动,清洗逻辑仍只有一份(redactSecrets)。 limit <= 0 = 不截断,留给体积已自己界定的调用方。 - observability_logs.go:新增常量 `maxLogMsgRunes = 4096`(含注释说明为什么不是 80、也不是无上限:单条日志可能是 %v 的 MiB 级对象,1000 条会撑爆 JSON), adminLogOf 改用 `RedactTextLimited(e.Msg, maxLogMsgRunes)`。 - span props / 摘要侧不动,仍是 80(一个要摘要,一个要全文,两边不该被统一)。 测试(均验过变异打红): - TestAdminObservabilityLogs_LongLineKeepsFullText:547 rune 的日志行(行首凭据 + 行尾哨兵)⇒ 凭据打码、末尾哨兵仍在、rune 数只差「凭据→[redacted]」那一处; 变异(改回 RedactText 80)⇒ 红:拿到 81 rune、末尾哨兵消失。 - TestAdminObservabilityTrace_PropsStayAtSummaryBound:200 rune 的 args_summary ⇒ 81 rune(80 + 省略号);变异(把 maxSummaryRunes 提到 4096)⇒ 红。 验收:go build ./... / go vet ./... 全绿;go test -count=1 -race ./internal/services/gateway/... ./internal/runtime/trace/... 全绿。未 push。
This commit is contained in:
1 parent
fa5d3d23bf
commit
3157abcf3c
3 files changed
+152
-8
No files matched your search
@@ -62,7 +62,27 @@ func IsSecretKey(key string) bool {
|
||||
// to maxSummaryRunes, so a published string can never carry a secret or an
|
||||
// unbounded blob.
|
||||
func RedactText(s string) string {
|
||||
return truncate(redactSecrets(s), maxSummaryRunes)
|
||||
return RedactTextLimited(s, maxSummaryRunes)
|
||||
}
|
||||
|
||||
// RedactTextLimited 是 RedactText 的**带上限**形态:同一套凭据形状清洗,截断长度
|
||||
// 由调用方给。它存在的理由是两个读面要的不是同一种东西 ——
|
||||
//
|
||||
// - **出图 / 摘要面**(span props、事件正文、工具结果摘要)要的是摘要 ⇒
|
||||
// `maxSummaryRunes`(80)足够,且保证一屏可读。这些调用方继续用 `RedactText`;
|
||||
// - **日志面**(`GET /admin/observability/logs` 的一行)要的是**可排障的全文** ⇒
|
||||
// 80 会把长错误行拦腰截断,等于丢掉诊断信息。
|
||||
//
|
||||
// 但它绝不接受「无上限散用」:一条日志可能是 `%v` 出来的 MiB 级对象,原样塞进
|
||||
// JSON 响应会撑爆面板的帧与响应体。因此上限**必须由调用方显式给出**并写清理由
|
||||
// (网关侧见 `maxLogMsgRunes`)。
|
||||
//
|
||||
// limit <= 0 表示**不截断**(只打码),留给「体积已由自己界定」的调用方。
|
||||
//
|
||||
// 🔴 清洗逻辑仍然只有一份(redactSecrets):上限是参数,不是第二条脱敏路径 ——
|
||||
// 另写一套必然漂移,而漂移的方向总是「其中一面开始原样吐凭据」。
|
||||
func RedactTextLimited(s string, limit int) string {
|
||||
return truncate(redactSecrets(s), limit)
|
||||
}
|
||||
|
||||
// RedactEvent returns ev with every string value — including those nested in maps
|
||||
|
||||
Reference in new issue
Block a user