一、Trace-ID注入与传播type Req = { headers: Record<string, string | undefined> } type Res = { setHeader: (k: string, v: string) => void } function randId(): string { return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2) } function attachTrace(req: Req, res: Res): string { const id = req.headers['x-trace-id'] || randId() res.setHeader('X-Trace-Id', id) return id } 二、采样与速率限制class RateGate { windowMs: number max: number hits = new Map<string, number[]>() constructor(windowMs: number, max: number) { this.windowMs = windowMs; this.max = max } allow(key: string): boolean { const now = Date.now() const arr = (this.hits.get(key) || []).filter(t => now - t < this.windowMs) if (arr.length >= this.max) return false arr.push(now); this.hits.set(key, arr); return true } } function sample(p: number): boolean { return Math.random() < p } 三、脱敏与Schematype LogItem = { traceId: string; level: 'info' | 'warn' | 'error'; route: string; method: string; status?: number; userId?: string; payload?: Record<string, any>; timestamp: string } function redactPII(obj: Record<string, any>): Record<string, any> { const out: Record<string, any> = {} for (const [k, v] of Object.entries(obj)) { const key = k.toLowerCase() if (key.includes('password') || key.includes('secret') || key.includes('token')) out[k] = '***' else if (key.includes('email')) out[k] = String(v).replace(/^[^@]+/, '***') else out[k] = v } return out } 四、日志输出与审计function nowIso(): string { return new Date().toISOString() } function makeLog(traceId: string, route: string, method: string, level: 'info' | 'warn' | 'error', payload?: Record<string, any>, status?: number, userId?: string): LogItem { const p = payload ? redactPII(payload) : undefined return { traceId, level, route, method, status, userId, payload: p, timestamp: nowIso() } } function serializeLog(item: LogItem): string { return JSON.stringify(item) } 五、整合中间件type Ctx = { req: Req; res: Res; route: string; method: string; userId?: string } function loggingMiddleware(ctx: Ctx, gate: RateGate, p: number, emit: (line: string) => void) { const traceId = attachTrace(ctx.req, ctx.res) const ok = gate.allow(traceId) if (!ok) return if (sample(p)) emit(serializeLog(makeLog(traceId, ctx.route, ctx.method, 'info', undefined, undefined, ctx.userId))) } 六、验收清单`X-Trace-Id`注入与传播一致;采样概率与速率限制生效。PII字段脱敏覆盖密码/Secret/Token与邮箱前缀;日志Schema统一且JSON输出。审计记录包含`traceId/route/method/status/userId/timestamp`并可关联上下游。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
2.158972s