mcpField
A
analyze-logs

analyze-logs

github.com/evloghq开发1.9k246 次安装2 天前更新
代码仓库

关于 analyze-logs

通过分析本地保存的 evlog 宽事件日志来排查应用行为的技能,可帮助开发者检查错误、慢请求、请求记录及行为模式,并可使用 CLI 或直接读取日志文件。

主要功能

  1. 01使用 evlog CLI 查询日志
  2. 02按时间、状态、路径或字段筛选
  3. 03检查错误和慢请求
  4. 04按请求 ID 跟踪事件
  5. 05读取文件系统及内存日志

适用场景

  1. 01排查近期应用错误
  2. 02查找缓慢的端点和请求
  3. 03检查指定请求 ID 的活动
  4. 04比较不同路由的错误模式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/evloghq/evlog --skill analyze-logs

安装后在 Claude Code 中输入/analyze-logs确认已加载。

详细介绍

分析应用日志

读取并分析本地 .evlog/logs/ 目录中的结构化宽事件日志,以调试错误、调查性能问题并了解应用行为。

适用场景

  • 用户要求调试错误、调查 Bug 或了解某项功能为何失败
  • 用户询问请求模式、响应缓慢的端点或错误率
  • 用户询问应用“发生了什么”或“现在是什么情况”
  • 用户要求分析日志、检查近期错误或查看应用行为
  • 用户提及他们遇到的特定错误消息或状态码

查找日志

优先尝试 CLI;它会读取两种文件布局、所有日期的文件,并且知道项目的日志写入器将日志写到哪里。优先使用项目安装的副本(pnpm evlog,或适用于其包管理器的等效命令)。按需获取的封装命令(npx、bunx、npm exec)会在项目尚未安装 @evlog/cli 时安装它,而运行的版本并未由锁文件固定。发生这种情况前,请先询问。

pnpm evlog logs --json                       # the last 50 events
pnpm evlog logs errors --since 1h --json     # what failed
pnpm evlog logs slow --over 1s --json        # what was slow, worst first
pnpm evlog logs "$REQUEST_ID" --json         # one request, every event with that id
pnpm evlog logs stats --json                 # per route: count, errors, p50, p95; by status and level
pnpm evlog logs --where 'payment.amount>5000' --where audit.outcome=failure --json

--json 输出的是一个信封对象(包含 sources、view、matched、events;stats 则包含 stats);筛选选项包括 --since、--until、--level、--path、--status(500 或 5xx)、可用于任意点分字段的 --where field=value|field>n|field~regex|field|!field(可重复指定)、--limit、用于指定非默认目录的 --dir,以及用于通过 HTTP 访问暴露 readMemoryLogs() 的内存日志写入器中的应用的 --url。从 monorepo 根目录运行时,它会读取所有应用的 .evlog/logs 并为每条事件添加标签。文档:https://www.evlog.dev/cli/logs。如果 CLI 不可用或用户拒绝使用,请按下文直接读取文件。

evlog 的文件系统日志写入器会将日志写入按日期组织的 .jsonl 文件。

格式检测:日志写入器支持两种模式:

  • NDJSON(默认,pretty: false):每行一个紧凑的 JSON 对象。逐行解析。
  • Pretty(pretty: true):每条事件使用多行缩进 JSON。可以读取整个文件并按顶层对象拆分(例如,JSON.parse('[' + content.replace(/\}\n\{/g, '},{') + ']')),也可以使用流式 JSON 解析器。

始终检查文件的前几个字节以检测格式:如果第二个字符是换行符或 ",则为 NDJSON;如果是空格,或换行符后跟空格,则为 pretty 格式。

搜索顺序。 检查相对于项目根目录的以下位置:

  1. .evlog/logs/(默认)
  2. 应用目录中的任何 .evlog/logs/(monorepo:apps/*/.evlog/logs/)

使用 glob 查找日志文件:

.evlog/logs/*.jsonl
*/.evlog/logs/*.jsonl
apps/*/.evlog/logs/*.jsonl

文件以日期命名:2026-03-14.jsonl。从最新的文件开始。

以编程方式读取:无需手动解析,可以使用 evlog 提供的读取器编写小脚本:evlog/fs 中的 readFsLogs() 和 tailFsLogs() 是异步生成器,可处理两种格式、日期排序和筛选。如果项目已安装 evlog,且分析所需操作不止快速 grep,请优先使用它们。

内存日志写入器替代方案:某些应用会使用 Memory 适配器(evlog/memory),而非(或同时使用)FS 日志写入器,并通过仅限开发环境的 HTTP 端点使用 readMemoryLogs() 暴露近期事件。如果 .evlog/logs/ 为空,但应用接入了 createMemoryDrain(),请改为查询该端点。

如果没有找到日志

在接入新的日志写入器前,可以尝试 npx evlog doctor --json,它会检查是否安装了 evlog,以及是否已存在本地 .evlog/logs 日志写入器(只读)。此步骤可选;如果 CLI 不可用,请跳过。

文件系统日志写入器可能未启用。对于 Nuxt、Nitro、Next.js、TanStack Start、Hono、Express 或 Fastify,最快的方法是使用 CLI;它会检测框架并一次性接入 fs 日志写入器(其默认开发日志写入器):

npx evlog init --dry-run --yes   # preview first
npx evlog init --yes --drain fs  # apply

运行前请先询问。对于其他框架(或用户拒绝时),请指导用户手动设置:

import { defineEvlog } from 'evlog'
import { createFsDrain } from 'evlog/fs'

// Nuxt / Nitro: evlog.config.ts at the app root, which the module loads
export default defineEvlog({ drain: createFsDrain() })

// Hono / Express / Elysia: pass in middleware options
app.use(evlog({ drain: createFsDrain() }))

// Fastify: pass in plugin options
await app.register(evlog, { drain: createFsDrain() })

// NestJS: pass in module options
EvlogModule.forRoot({ drain: createFsDrain() })

// Standalone: pass to initLogger
initLogger({ drain: createFsDrain() })

设置完成后,用户需要触发一些请求以生成日志,然后重新分析。

日志格式

每一行都是一个独立的 JSON 对象(宽事件)。主要字段:

字段类型说明
timestampstringISO 8601 时间戳
levelstringinfo、warn、error、debug
servicestring服务名称
environmentstringdevelopment、production 等
methodstringHTTP 方法(GET、POST 等)
pathstring请求路径(/api/checkout)
statusnumberHTTP 响应状态码
durationstring请求耗时,使用便于阅读的格式("234ms")
durationMsnumber请求耗时,单位为毫秒。请使用此字段进行筛选和排序
requestIdstring唯一请求标识符
errorobject错误详情:name、message、stack、statusCode、data
error.data.whystring对出错原因的易读说明
error.data.fixstring针对错误的修复建议
sourcestring浏览器日志为 client;服务器日志中不存在此字段
userAgentobject解析后的浏览器/操作系统/设备信息

所有其他字段均为通过 log.set() 添加的应用专属上下文(例如 user、cart、payment)。

如何分析

步骤 1:读取最新的日志文件

读取最新的 .jsonl 文件。每一行都是一个 JSON 事件。分别解析每一行。

步骤 2:找出相关事件

根据用户的问题进行筛选:

  • 错误:"level" 为 "error" 或 "fatal"、status >= 500,或事件中包含 error 对象;这也是 evlog logs errors 的匹配规则。单独出现 4xx 状态码不算客户端错误,但如果 4xx 事件还带有另外两个信号之一,也会匹配;读取 status 或传入 --status 4xx 可查看所有此类事件
  • 特定端点:按 path 匹配
  • 慢请求:按 durationMs 筛选(例如 durationMs > 500)
  • 特定用户/操作:按应用专属字段匹配
  • 客户端问题:按 "source":"client" 筛选
  • 时间范围:比较 timestamp 值
步骤 3:分析并说明

针对每个相关事件:

  1. 发生了什么:概述 path、method、status、level
  2. 失败原因(错误):查看 error.message、error.data.why 和堆栈跟踪
  3. 如何修复:查看 error.data.fix 中的修复建议
  4. 上下文:检查应用专属字段,了解业务背景(用户信息、付款详情等)
  5. 模式:查找重复出现的错误、性能下降或相关故障

分析模式

查找所有错误
Filter: level === "error"
Group by: error.message or path
Look for: recurring patterns, common failure modes
查找慢请求
Filter: durationMs > 1000
Sort by: durationMs descending
Look for: specific endpoints, time-of-day patterns
跟踪特定请求
Filter: requestId === "the-request-id"
Result: single wide event with all context for that request
按端点统计错误率
Group events by: path
Count: total events vs error events per path
Look for: endpoints with high error ratios
客户端与服务器错误
Split by: source === "client" vs no source field
Compare: error patterns between client and server
Look for: client errors that don't have corresponding server errors (network issues)

重要说明

  • 每一行都是一个完整、独立的事件。与传统日志不同,你无需关联多行日志。一行就包含了一个请求的所有上下文。
  • error.data.why 和 error.data.fix 字段是 evlog 专用的结构化错误字段。存在这些字段时,它们会提供最具可操作性的信息。
  • duration 使用带单位的易读格式(例如 "706ms")。durationMs 表示相同的耗时,单位为毫秒;请使用 durationMs 进行筛选和排序。
  • "source":"client" 的事件源自浏览器端日志,并通过 HTTP drain 端点发送到服务器。
  • 日志文件会自动加入 .gitignore。它们仅存在于运行应用的本地计算机或服务器上。

评论

支持 Markdown