一、事件Schematype Evidence = { id: string; type: 'csp' | 'error' | 'perf' | 'suspect'; detail: string; url: string; traceId?: string; userId?: string; ts: string }
二、Trace-ID与采样function randId(): string { return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2) }
function attachTrace(existing?: string): string { return existing || randId() }
function sample(p: number): boolean { return Math.random() < p }
三、脱敏与结构化function redact(e: Evidence): Evidence {
const out = { ...e }
out.detail = out.detail.replace(/(token|password|secret)=([^&\s]+)/gi, '$1=***')
return out
}
function serialize(e: Evidence): string { return JSON.stringify(e) }
四、采集中间件type Ctx = { userId?: string; traceId?: string; endpoint: string; fetchFn: (url: string, body: string) => Promise<void> }
async function collect(ctx: Ctx, e: Omit<Evidence,'id'|'ts'>, p: number) {
const ev: Evidence = { id: randId(), type: e.type, detail: e.detail, url: e.url, traceId: attachTrace(ctx.traceId), userId: ctx.userId, ts: new Date().toISOString() }
if (!sample(p)) return
const body = serialize(redact(ev))
await ctx.fetchFn(ctx.endpoint, body)
}
五、指标聚合(示意)class Metrics { counts = new Map<string, number>(); inc(key: string) { const n = (this.counts.get(key) || 0) + 1; this.counts.set(key, n) } }
function keyOf(type: string, url: string): string { try { const u = new URL(url); return `${type}:${u.origin}` } catch { return `${type}:${url}` } }
六、验收清单事件Schema最小化且类型明确;Trace-ID关联上下游;采样概率可控。脱敏覆盖敏感键;结构化JSON输出;上报端点可用与速率受控。指标按`type:origin`聚合;演练记录包含事件ID、时间与用户上下文。

发表评论 取消回复