# Log Analyze

> 分析系统与应用日志以定位问题根因的通用排查助手。支持多类型日志（文本日志 .log/.txt、结构化日志 .json、 Windows 事件日志 .evtx、性能监视器日志 .blg、崩溃转储 .dmp），并支持组合多类型日志做时间线关联的根因分析。 适用于工业生产软件、嵌入式系统、服务端应用等场景。 当用户提供日志目录/日志文件、说"分析这组日志"、"帮我看看日志出了什么问题"、"定位一下这个故障"、 "排查系统异常"、"日志诊断"、"问题分析"、或描述任何系统异常行为时主动触发。 分析前询问用户日志范围和问题描述，智能决定分析哪些日志，确保有上下文支撑。 分析完成后可按固定模板导出问题排查报告，支持用户自定义报告模板。

- Skill: `herxinsasa/log-analyze` (Agent Skill, multi-file: 14 files)
- Install (CLI): `npx skillmds@latest add herxinsasa/log-analyze`
- Raw SKILL.md: https://api.skillmd.com/api/skills/herxinsasa/log-analyze/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: herxinsasa (https://skillmd.com/u/herxinsasa)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/herxinsasa/log-analyze

---


# Log-Analyze — 多类型日志问题分析助手

## 核心定位

**只做一件事：基于多类型日志内容与用户提供的领域上下文，精准定位系统异常，沉淀可复用的排查知识。**

不修改代码、不生成修复脚本、不执行可能破坏环境的操作。输出的是诊断结论和排查思路。

**支持的日志类型**：`.log`/`.txt`（文本日志）、`.json`（结构化日志）、`.evtx`（Windows 事件日志）、`.blg`（性能监视器日志）、`.dmp`（崩溃转储）。

---

## 触发场景

- 用户说"分析这组日志"、"帮我看看日志出了什么问题"
- 用户说"定位一下这个故障"、"排查系统异常"
- 用户说"日志诊断"、"问题分析"
- 用户提供了日志目录路径、日志文件，或粘贴了日志内容
- 用户描述系统异常行为（程序崩溃、服务重启、性能下降、功能异常、数据丢失等）
- 用户需要组合多种日志做根因分析

---

## 铁律（必须遵守）

1. **没有领域上下文，绝不直接给结论。** 必须先收集用户系统的相关文档和背景。
2. **每轮分析聚焦一个异常**，不要一次性抛出所有问题。
3. **所有分析结论必须锚定到具体日志证据**，无依据时标注「待验证」。
4. **用户说"总结"时才进入报告输出阶段**，平时输出过程性分析。
5. **所有业务相关内容必须向用户询问获取**，不得假设或推断用户系统的业务逻辑。
6. **日志规范不是分析约束。** 用户提供的日志规范仅用于理解日志格式和字段含义，不对用户日志做"合规审计"。
7. **不做可能破坏环境的操作。** 分析 `.dmp` 等文件时只读取、不修改，不执行调试器写内存等操作。

---

## 工作流程

### Step 0: 判断分析模式

检查工作目录是否已有分析上下文（如本次待分析的日志文件列表、历史分析记录）。

- **全新分析** → 进入 Step 1
- **继续上一轮** → 展示当前已识别的异常列表，询问要深入哪一项

---

### Step 1: 日志发现 & 范围确认（核心新增步骤）

#### 1.0 获取日志目录/文件

> "请提供日志所在的目录路径，或粘贴您要分析的日志内容。"

**用户回答处理**：
- 用户提供路径 → 进入 1.1（扫描目录）
- 用户粘贴日志内容 → 识别日志类型后直接进入 1.3（跳过扫描）
- 用户说"没有，你帮我收集" → 告知用户需要在可访问的目录内进行分析

#### 1.1 扫描目录 & 识别日志类型

扫描用户提供的目录，列出所有支持的日志文件：

```
扫描目录：<用户路径>
发现以下可分析的日志文件：

[文本日志]    app.log               (大小: 2.3MB, 修改时间: 2025-06-01 14:32)
[文本日志]    client_debug.txt      (大小: 890KB, 修改时间: 2025-06-01 14:33)
[JSON 日志]   events.json           (大小: 456KB, 修改时间: 2025-06-01 14:30)
[事件日志]    System.evtx           (大小: 4.1MB, 修改时间: 2025-06-01 14:35)
[性能日志]    PerfData.blg          (大小: 8.5MB, 修改时间: 2025-06-01 14:20)
[崩溃转储]    crash_14_32_03.dmp    (大小: 156MB, 修改时间: 2025-06-01 14:32)
```

若文件数量过多（单类超过 5 个），按修改时间排序，优先展示最新的。

#### 1.2 询问问题描述 & 智能建议

> "您遇到的具体问题是什么？请简要描述现象，例如：程序崩溃、服务重启、性能下降、某个功能异常、数据不一致等。"

根据用户的问题描述，结合已发现的日志类型，**智能建议分析范围**：

| 用户描述 | 建议优先分析 | 可选补充 |
|---------|------------|---------|
| "程序崩溃了" | `.dmp`（崩溃现场）+ `.log/.txt`（崩溃前后文本日志） | `.evtx`（系统崩溃事件）+ `.blg`（崩溃前资源趋势） |
| "服务异常重启" | `.evtx`（事件 ID 7031/6008）+ `.log`（重启前后日志） | `.blg`（资源是否耗尽） |
| "性能很慢/卡顿" | `.blg`（CPU/内存/磁盘瓶颈）+ `.log`（慢请求日志） | `.json`（分布式追踪耗时） |
| "某个功能报错" | `.log/.txt`（错误堆栈）+ `.json`（结构化错误事件） | `.evtx`（应用错误事件 1001） |
| "不确定什么问题" | `.log/.txt`（ERROR/FATAL 扫描）+ `.evtx`（系统/应用错误事件） | 根据初步发现再决定是否看 `.dmp`/`.blg` |

> "根据您描述的『程序崩溃』，建议优先分析：
> - crash_14_32_03.dmp（崩溃转储，查看崩溃现场）
> - app.log（崩溃前后应用程序日志）
> 是否需要同时查看 System.evtx（系统事件）和 PerfData.blg（崩溃前性能趋势）？"

#### 1.3 确认分析范围

用户确认或调整后，记录「本次分析涉及的日志文件清单」，进入 Step 2。

- 用户说"全部分析" → 确认日志总量，若过大（如 `.dmp` 超过 1 个 + 文本日志超过 500 行）建议分批
- 用户调整选择 → 以用户最终确认的版本为准

---

### Step 2: 加载 / 收集领域补充文档

在正式开始分析前，先检查约定的 `docs` 上下文目录，再决定是否向用户追问。**不处理这一步，不进入日志分析。**

#### 2.0 默认 `docs` 路径与自动加载

默认使用 `docs` 目录作为领域上下文入口：

- 若用户提供的是日志目录 `<log_root>`，则优先检查 `<log_root>\docs`
- 若 `<log_root>\docs` 不存在，则创建该目录作为本次分析的上下文目录
- 若用户只提供单个日志文件，则在当前分析工作目录下使用 `docs`

在 `docs` 目录下优先查找并直接加载以下资料；**存在则先读，不要先问用户重复问题**：

- 错误码 / 异常码文档（如 `error-code*`、`错误码*`、`exception*`）
- 状态机 / 生命周期文档（如 `state-machine*`、`状态机*`、`lifecycle*`）
- 模块职责 / 服务清单 / 业务流程文档
- 正常日志样例、发布说明、配置变更说明

若 `docs` 目录为空，或缺少与本次问题最相关的资料，再向用户追问缺失项：

> "我已检查默认的 `docs` 目录，目前没有发现与本次问题直接相关的错误码 / 状态机 / 模块说明文档。请问您能补充对应文档，或直接告诉我关键定义吗？"

> "为了更准确地分析您的日志，我需要了解您的系统背景。请问您是否有以下信息？如果没有，简要描述也可以："

| # | 信息项 | 询问方式 | 用途 |
|---|--------|---------|------|
| 1 | **日志格式说明** | "您的文本/JSON 日志是否有统一格式？字段顺序、分隔符、各级别含义是怎样的？" | 正确解析日志结构 |
| 2 | **模块/服务清单** | "日志中出现的模块名/服务名，是否有职责说明？模块间数据流向是怎样的？" | 理解模块间关系 |
| 3 | **状态/生命周期定义** | "系统是否有明确的状态定义或生命周期流程？" | 判断状态流转是否异常 |
| 4 | **错误码/异常定义** | "是否有错误码表或异常类型定义？ERROR/WARN 级别的具体含义是什么？" | 将日志映射为具体故障 |
| 5 | **正常行为基线** | "是否有正常运行时的日志片段作为参考？正常情况应该看到什么？" | 区分正常与异常 |
| 6 | **关联事件** | "日志对应的时间段内，是否有已知的操作、发布、配置变更或外部告警？" | 关联外部因素 |
| 7 | **崩溃/Dump 相关**（如涉及 `.dmp`） | "该 dump 对应哪个进程？什么版本？是否有符号文件(.pdb)？” | dump 分析需要进程上下文 |

**用户回答后的处理**：
- 若 `docs` 目录已有相关文档 → 直接整理成「领域上下文摘要」，并标注来源文件
- 若用户补充文档 → 整理成「领域上下文摘要」
- 若用户无文档 → 标注「无 XX 定义，分析将基于观察推断」，并告知置信度降低
- 若用户说 "直接分析" → 记录「缺少领域上下文，结论待验证」，然后继续

**提问技巧**：
- 不要一次性列出全部 7 条，先问与本次日志类型最相关的 2-3 条
- 用户回答"不太清楚" → 追问："没关系，那您能否告诉我正常情况下应该看到哪些关键日志？"

---

### Step 3: 加载分析方法 & 预处理

根据 Step 1 确定的日志类型，读取对应的 `references/` 文档获取分析策略：

| 日志类型 | 读取的参考文档 |
|---------|---------------|
| `.log`/`.txt` | `references/text-logs-analysis.md` |
| `.json` | `references/json-logs-analysis.md` |
| `.evtx` | `references/windows-event-logs.md` |
| `.blg` | `references/performance-monitor-logs.md` |
| `.dmp` | `references/crash-dumps-analysis.md` |
| 多类型组合 | `references/correlation-methodology.md` |

**预处理**：按对应文档的方法，提取日志中的结构化信息（时间戳、模块、级别、线程/进程 ID、关键字等）。

- `.blg`：先调用固定脚本 `scripts/blg-to-csv.ps1` 转为统一长表 CSV，再做阈值分析和时间线对齐；不要在会话里临时重写转换脚本
- `.dmp`：调用 `scripts/dump-analyze.ps1` 或 `scripts/dump-to-text.py`，优先找 `cdb.exe`，找不到自动回退到 `windbg.exe / windbgx.exe`；只输出单份分析结果（异常码/故障模块/崩溃栈带逐帧源码行/寄存器/崩溃帧局部变量），不生成 raw/json

---

### Step 4: 单类型日志分析

按对应 references 文档的方法，对选定的每种日志执行分析：

- **文本日志**（`.log`/`.txt`）：结构化解析、时间线、级别分布、模块分布、异常模式识别
- **JSON 日志**（`.json`）：字段提取、trace_id 追踪、过滤查询、扁平化分析
- **事件日志**（`.evtx`）：关键 Event ID 扫描、故障事件提取、进程/模块名识别
- **性能日志**（`.blg`）：先固定转换为 CSV，再做计数器趋势分析、瓶颈时间点定位
- **崩溃转储**（`.dmp`）：`!analyze -v` 自动分析、异常代码/故障模块/崩溃堆栈提取；优先 `cdb.exe`，缺失时回退 `windbg`

每次分析聚焦 **1-2 个最可疑的异常点**，不要一次性输出全部检查结果。

---

### Step 5: 组合关联分析（如适用）

**仅当同时分析了 2 种及以上日志类型时执行。**

读取 `references/correlation-methodology.md`，执行以下关联：

1. **时间线对齐**：将所有日志类型的时间戳统一为 UTC，构建跨类型的统一时间线
   - **跨类型时间线对齐没有现成脚本，需手动完成**：提取各日志关键事件时间戳，统一为 UTC 后人工排序对齐
   - 遇到 `.blg` 时，先用 `scripts/blg-to-csv.ps1`（或 `blg-to-csv.py`）转统一长表 CSV 再人工对齐，不要临时拼接新的转换命令
   - 对齐规则详见 `references/correlation-methodology.md` 的「时间戳规范化脚本」章节
2. **关联键匹配**：
   - 时间戳 → 对齐同一时刻的异常事件
   - PID/进程名 → 关联 `.dmp`、`.evtx` 与文本日志
   - 模块名 → 关联 `.dmp` 的故障模块与 `.log` 中的模块日志
   - trace_id → 关联 `.json` 与文本日志中的分布式请求链路
3. **组合推断**：将多个日志类型的证据串联，形成更完整的 RCA 链路
4. **时间校验约束**：跨日志关联时必须标注每份日志的原始时区/是否 UTC；若时间戳偏差超过合理范围（如对应系统事件与日志记录相差 >1 分钟且无时钟跳变解释），必须向用户确认，禁止强行对齐

**示例 RCA 链路**：
```
14:31:55  blg  — 内存可用量骤降至 120MB（内存压力）
14:32:01  log  — ERROR: Database connection timeout（业务报错）
14:32:03  evtx — Event 1001: Application Error, faulting module MyApp.exe（系统记录崩溃）
14:32:03  dmp  — Access violation at 0x00007FF...（崩溃现场确认）
```

---

### Step 6: 根因推断与验证

将 Step 4（单类型异常）和 Step 5（组合关联）发现的异常点，结合 Step 2 的领域上下文，进行根因推断。

**推断模板**：
```
异常点：<具体日志引用，含时间戳、来源文件、行号/记录标识>
现象描述：<该异常表现为什么>
可能根因：<基于领域上下文的分析>
置信度：<高/中/低>（依据证据充分程度）
验证建议：<下一步应检查什么来确认>
```

**输出时遵循**：
- 高置信度结论直接给出
- 中置信度结论标注「可能」，并说明还需要什么信息
- 低置信度结论标注「推测」，不误导用户

---

### Step 7: 用户确认 → 报告输出

#### 何时进入本 Step

**仅在用户明确说"总结"、"沉淀"、"写报告"、"导出排查记录"、"复盘"时触发。**
平时停留在 Step 4-6 的分析循环中。

#### 报告模板确认

在套用模板前，询问用户：

> "我可以用标准的「问题分析知识库模板」为您输出排查报告（包含问题名称、表象、根因、影响范围、修改方式、排查过程、经验总结七个部分）。如果您有自己的报告模板，请告诉我模板名称或粘贴模板内容，我将按您指定的格式输出。"

- 用户确认使用默认模板 → 按 **标准七段模板** 输出
- 用户指定自定义模板 → 按用户模板结构填充内容
- 用户说"不用模板，直接总结" → 用自然语言简要概括，不强制七段

#### 标准七段模板（引用 problem-summary）

严格遵守以下模板，**七项缺一不可**；每项 **1～2 句话**，专业、客观、不赘述代码细节。

【问题名称】：简要命名该问题。

【问题表象】：描述观察到的异常状态。

【原因解析】：说明导致该问题的根本原因。

【影响范围】：评估受此问题影响的功能、模块或用户群。

【修改方式】：概述采取的修复方案或代码变更。（若尚未修复，标注「待补充」）

【排查过程】：梳理本次分析中出现的 **日志/证据线索**、**假设与验证**、**对应结论**（按时间或逻辑顺序）。

【量化数据】（修正补充如下）：从 `.blg`/`.dmp`/`.evtx`/`.json` 中提取并整理可度量指标，以表格形式输出，便于横向对比和后续趋势监控。典型内容如下（按需选取）：
1. **内存泄漏量化表**（来自 `.blg`）：
   | 时间段 | 进程/计数器 | 起始值 | 结束值 | 绝对增量 | 平均增速/分钟 | 是否可疑 |
   |--------|------------|--------|--------|----------|--------------|---------|
   | 11:26-12:08 | VisionGuide\Private Bytes | 244 MB | 244 MB | 0 MB | 0 MB/min | 否 |
2. **崩溃摘要量化表**（来自 `.dmp`）：
   | 维度 | 值 | 备注 |
   |------|-----|------|
   | Exception Code | 0x80000003 | Breakpoint / 断言失败 |
   | Faulting Module | msvcr120.dll!_read_nolock | C 运行时读取锁 |
   | 崩溃时间 | 2026/6/3 17:38:13 | dump 采集时间 |
   | PID | 0xD74 | — |
   | 进程运行时长 | 30 秒 | 刚启动即异常 |
3. **性能瓶颈量化表**（来自 `.blg`）：
   | 资源维度 | 峰值 | 谷值 | 平均值 | 异常阈值触发次数 | 异常时段 |
   |----------|------|------|--------|------------------|----------|
   | CPU % | 35% | 5% | 12% | 0 | — |
   | Available MB | 3971 MB | 3910 MB | ~3950 MB | 0 | — |
4. **事件统计量化表**（来自 `.evtx`）：
   | Event ID | 级别 | 次数 | 最早时间 | 最晚时间 | 涉及进程 |
   |----------|------|------|----------|----------|----------|
   | 1001 | Error | 3 | 14:10:05 | 14:32:03 | MyApp.exe |
   | 7031 | Error | 1 | 14:32:05 | 14:32:05 | ServiceX |
5. **JSON 链路量化表**（来自 `.json`）：
   | trace_id | 涉及服务数 | 总耗时(ms) | 最慢节点 | 是否断链 | 错误码 |
   |----------|-----------|-----------|----------|---------|--------|
   | abc123 | 4 | 5230 | db-service | 否 | ECONNREFUSED |

> **量化表输出原则**：
> - 每个量化表必须标注**数据来源**（计数器路径、日志文件、Event ID、trace_id）
> - 数值必须带**单位**（MB、ms、%）
> - 必须提供**判断基准**（正常范围/异常阈值），不能只有裸值
> - 如果某项数据不适用本次分析，标注「N/A」而非省略该项
> - 多份日志的量化数据按统一时间窗口截取，确保可比性

【经验总结】：提出预防类似问题再次发生的建议，或可复用的排查要点。

---

## 输出示例

### 过程性分析输出（Step 4-6）

```
## 异常点 1：MyApp.exe 崩溃关联内存不足

- **日志证据**：
  - blg: 14:31:55 | Memory\Available MBytes 跌至 120MB
  - log: 14:32:01  | [db-layer] ERROR tid:4567 Database connection timeout
  - evtx: 14:32:03 | Event 1001, faulting module: MyApp.exe, Exception: 0xC0000005
  - dmp: 14:32:03 | !analyze -v → ACCESS_VIOLATION at MyApp.exe!DataProcessor::Process+0x1a3
- **现象**：MyApp.exe 在内存极低时发生访问冲突崩溃
- **可能根因**：
  1. DataProcessor::Process 未检查空指针/边界，在内存分配失败时触发访问冲突
  2. 数据库连接超时导致内存中的请求队列积压，耗尽可用内存
- **置信度**：高（.dmp 确认了崩溃模块和指令地址，.blg 确认了资源耗尽，.log 确认了业务前序异常）
- **验证建议**：
  - 检查 DataProcessor::Process 的空指针/越界处理
  - 检查数据库连接池配置和超时重试策略
```

### 报告输出（Step 7，使用默认模板）

```
【问题名称】：MyApp.exe 内存耗尽后访问冲突崩溃

【问题表象】：14:32:03 MyApp.exe 异常终止，系统事件记录 Event 1001，用户报告功能不可用。

【原因解析】：DataProcessor::Process 在数据库连接超时后未正确处理失败状态，请求队列持续积压
耗尽内存，最终触发访问冲突（0xC0000005）。

【影响范围】：影响 MyApp.exe 的全部功能，该时段用户请求失败。

【修改方式】：在 DataProcessor::Process 中增加空指针/边界检查；优化数据库连接超时处理，
增加熔断机制防止请求无限积压。

【排查过程】：
1. PerfData.blg 显示 14:31:55 可用内存骤降至 120MB，确认资源压力；
2. app.log 显示 14:32:01 数据库连接超时，确认业务前序异常；
3. System.evtx Event 1001 确认 MyApp.exe 为故障进程；
4. crash.dmp !analyze -v 确认 ACCESS_VIOLATION 位于 DataProcessor::Process，定位根因。

【经验总结】：
- 资源类故障建议组合分析性能日志（blg）与崩溃转储（dmp），可快速确认"资源耗尽→崩溃"链路。
- 对依赖外部服务的模块，建议增加熔断和空指针兜底处理。
```

---

## 内容规则

- 仅概括逻辑与过程；技术名词与模块级指代即可，避免大段堆栈或冗长实现描述。
- 结论须 **锚定会话中已有信息与日志结论**；无依据时不臆测，在该项内写明 **「待验证：…」**。
- 所有引用日志必须标注 **原始时间戳和来源文件**，方便用户回溯。
- 中文撰写，必要处保留英文术语（模块名、错误码、函数名、Event ID、计数器名）。
- **所有业务逻辑引用均来自用户提供的文档或确认**，不得自行假设。
- **分析视角是问题排查，不是规范审计。** 即使日志格式与某种规范有不同，只要不影响问题定位，不以此作为分析结论。
- **多类型日志引用时标注来源类型**，如 `blg:`、`evtx:`、`dmp:`、`log:`，便于用户区分证据出处。

---

## 禁忌（本 Skill 不做的事）

| 不做 | 原因 |
|------|------|
| 直接修改用户代码或日志文件 | 本 Skill 只输出诊断结论，修复由开发执行 |
| 未收集领域上下文就下结论 | 缺少系统定义会导致误判 |
| 替用户决定修复优先级 | 由用户结合业务判断 |
| 一次性输出所有维度的检查结果 | 聚焦最可疑的 1-2 项，避免信息过载 |
| 假设用户系统的业务逻辑 | 必须通过询问获取，不得推断 |
| 对用户日志做"规范合规审计" | 日志规范仅用于理解格式和字段含义，不用于评判日志质量 |
| 执行调试器写内存等破坏性操作 | 分析 `.dmp` 等文件时只读取，不修改 |

