用途
review-logging-patterns 用于审查并改进 TypeScript/JavaScript 代码库中的日志模式:把散落的 console.log 转换为结构化的宽事件,把通用错误转换成自文档化的结构化错误。它同时用于在项目(任意受支持的框架)中接入 evlog、审查日志最佳实践、改进错误处理的上下文、以及配置日志排流、采样或富化。
主要能力
CLI 快速参考:
- 接入:
evlog init— 将 evlog 接入项目 - 项目约定:
evlog agents— 将 evlog 区块写入项目的 AGENTS.md - 覆盖度地图:
evlog map— 对未覆盖入口点打分 - CI 门禁:
evlog map --min-score / --baseline— 拦截回归
参考资料包括:宽事件模式(references/wide-events.md)、错误处理(references/structured-errors.md)、代码审查清单(references/code-review.md)、排流管道(references/drain-pipeline.md)。审计日志可参考 build-audit-logs 技能与文档。
审计日志:对于安全敏感操作(认证、计费、管理、数据导出),使用 evlog 的审计层——在宽事件上使用带类型的 audit 字段,而不是并行日志器。端到端设置见 build-audit-logs 技能(log.audit、withAudit、denials、auditEnricher、auditOnly、signed、mockAudit)。示例:
log.audit({
action: 'invoice.refund',
actor: { type: 'user', id: user.id },
target: { type: 'invoice', id: invoice.id },
outcome: 'success',
})
文档地址:https://www.evlog.dev/use-cases/audit/overview
安装与 CLI 使用方式
安装:npm install evlog
CLI 可执行文件随 evlog 包提供:pnpm evlog、npx evlog、bunx evlog。它在已安装时运行 @evlog/cli,否则按需拉取(不向项目添加依赖),因此在还没有任何内容的新项目上也能工作。它读取磁盘上的项目(不涉及流量、不需要配置)。在七个受支持的框架上覆盖完整闭环:接入(init)、评分覆盖度(map)、在 CI 中锁定分数(--min-score、--baseline)。如果 CLI 不可用、框架尚无适配器,或用户拒绝,可继续使用手动章节;该技能不依赖 CLI。安装任何东西前需先询问。
1. 设置:evlog init
对于尚未使用 evlog 的项目,优先使用 init 而非手写配置,因为它会检测框架、读取项目已有内容,并一次性生成配置、排流、富化器和附加项。它完全可脚本化:
# 预览一切而不写入(始终从这里开始)
npx evlog init --dry-run --yes
# 然后应用——用标志代替提示
npx evlog init --yes \
--service my-app \
--drain fs \
--prodDrain axiom \
--extras enrichers,pipeline,sampling \
--sampling medium
可用标志:--framework(覆盖检测:nuxt、nitro、next、tanstack-start、hono、express、fastify)、--prodDrain(逗号分隔:axiom、otlp、posthog、sentry、better-stack、datadog、hyperdx)、--extras(enrichers、pipeline、sampling、vite、error-catalog、audit-catalog、ai、better-auth)、--enrichers、--sampling(流量层级:all、low、medium、high、very-high)、--apps(monorepo:指定工作区包)、--no-install。应用前先与用户一起审查 --dry-run 输出。文档:https://www.evlog.dev/cli/init
2. 评分:evlog map
npx evlog map --no-write
# agents: npx evlog map --json --no-write
得到:项目分数以及哪些入口点仍未被覆盖;FIX FIRST:三个最有价值的修复位置;GOING FURTHER:不会扣分的机会(目录、审计覆盖、AI 日志、认证身份);按文件检查:npx evlog map <file> --no-write 展示处理器可采用的结构;修复后重新运行并观察分数变化。按顺序处理 FIX FIRST,保持改动最小(useLogger()、log.set()、log.audit()、createError({ why, fix })),然后以 --no-write 重新运行。仅当用户希望写入 evlog.map.json 时才省略 --no-write。
3. 在 CI 中锁定:--min-score 与 --baseline
在 GitHub Actions 上,建议使用 evlog action(uses: evloghq/action@v1 配 min-score):它自行扫描 PR 基础分支,因此无需提交 map 文件,并把回归放在 diff 和一条评论里。以下命令是 run: 步骤中的同一门禁。
修复后,建议让分数持久化:
# 在 CI 中,执行 pnpm add -D @evlog/cli 之后(由 lockfile 固定;先询问)
pnpm exec evlog map --min-score 80 # 绝对门禁:低于阈值退出 1
pnpm exec evlog map --baseline # 棘轮:如果本 PR 让情况变差则退出 1
--baseline 会把最新扫描与已提交的 evlog.map.json 逐入口点、逐要求比较,因此一个重构只给某条路由加了埋点、却弄坏了另一条,即使总分不变也会失败。用注释禁用一项已通过的检查同样算作回归。新的未埋点路由会列为 NEW AND DARK 但不导致失败。工作流:提交一次 evlog.map.json,把 --baseline 运行加入 CI,然后不带 --baseline 重跑 map 以接受有意的变更。文档:https://www.evlog.dev/cli/ci
早期阶段:适配器和规则仍在演进,分数可能随版本变化。文档:https://www.evlog.dev/cli/map · 规则:https://www.evlog.dev/cli/rules
框架接入
文档给出了 Nuxt、Next.js、SvelteKit、Nitro v3、TanStack Start、Nitro v2、NestJS、Express、Hono 的配置示例(模块注册、日志器获取方式、排流/富化/尾部采样、客户端传输、错误处理中间件等)。在 Nuxt 中 useLogger、log、parseError 自动导入,createError 需从 evlog 导入(裸的会解析到 h3 的,会丢掉 why、fix、link);Next.js 通过 lib/evlog.ts 集中配置并用 withEvlog() 包装路由处理器与 Server Actions,另有中间件、客户端 Provider、客户端日志与 ingest 端点;SvelteKit 通过 createEvlogHooks() 提供 handle 与 handleError,并可用 event.locals.log 或 useLogger();Express、Hono 通过中间件挂载并通过 req.log、c.get('log') 或 useLogger() 访问;NestJS 使用 EvlogModule.forRoot()(或 forRootAsync())。Cloudflare Workers 上 useLogger() 需要 nodejs_compat(或 nodejs_als)兼容标志,c.get('log') 不受此限制。结构化错误部分原文在“throw createError(), then in a”处截断,后续内容暂未提供。
适用场景
新项目或已有项目中接入 evlog、审查日志最佳实践、把 console.log 转为结构化日志、用更好的上下文改进错误处理、配置日志排流/采样/富化,以及为安全敏感操作建立审计日志。
限制
CLI 标注为早期阶段,适配器和规则仍在演进,分数可能随版本变化;并非所有框架都有适配器;该技能不依赖 CLI,CLI 不可用时可走手动路径;安装任何内容前需要先询问用户。原文中“Structured errors”一节内容不完整,其余未在资料中明确说明的限制暂未提供。