# Add Diag Logs

> 自动在代码中注入诊断日志，辅助定位 bug。触发场景：(1) 用户贴了错误日志/堆栈跟踪后调用 /add-diag-logs；(2) 用户要求"加点日志""加诊断日志""帮我定位问题""注入log"等调试辅助请求；(3) 调查 bug 时信息不足以定位根因，需要先加日志收集数据。仅注入日志，不修改业务逻辑。

- Skill: `grasscaograss/add-diag-logs` (Agent Skill)
- Install (CLI): `npx skillmds@latest add grasscaograss/add-diag-logs`
- Raw SKILL.md: https://api.skillmd.com/api/skills/grasscaograss/add-diag-logs/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: grasscaograss (https://skillmd.com/u/grasscaograss)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/grasscaograss/add-diag-logs

---


# 诊断日志注入

在代码的关键执行路径上注入 ILogger 诊断日志，帮助用户收集运行时数据以定位 bug。

## 输入分析

收到用户请求后，分析以下输入（优先级从高到低）：

1. **堆栈跟踪** — 解析文件名:行号，锁定异常抛出位置和调用链
2. **错误消息** — 根据异常类型和消息推断涉及的模块
3. **症状描述** — 用户口头描述的异常行为，需推断可能涉及的代码路径
4. **指定方法** — 用户直接指定的入口方法

## 定位策略

### 有堆栈跟踪时

1. 从堆栈底部（入口）到顶部（异常点）提取调用链中**本项目**的文件和行号
2. 对每个方法，识别：方法入口、关键分支(if/switch)、循环、return 前的值
3. 沿调用链向上追溯 2-3 层，覆盖数据传递的关键节点

### 无堆栈跟踪时

1. 根据错误信息搜索相关类/方法（Grep 关键词）
2. 识别主入口方法（通常是 Service/Manager/Handler 层的 public 方法）
3. 沿调用链展开 2-3 层深度
4. 重点关注：数据转换、条件分支、集合操作、外部调用

### 自动判断范围

- **错误信息明确**（如 NullReferenceException 在具体行）→ 聚焦该方法及其调用者
- **错误信息模糊**（如"结果不对""偶尔失败"）→ 扩大范围，覆盖整个流程链
- **涉及数据流**（如计算结果异常）→ 从数据入口到出口全链路加日志

## 注入规则

### 日志框架

- 使用 `ILogger`，**禁止** `Console.WriteLine`
- 通过构造函数 DI 注入 `ILogger<ClassName>`
- 如果类中已有 `_logger` 字段，直接使用

### 日志级别

| 级别 | 场景 |
|------|------|
| `LogInformation` | 方法入口/出口、关键数据值、分支走向 |
| `LogWarning` | 意外分支、边界条件、null/空集合 |
| `LogError` | catch 块中、异常重抛前 |

### 日志内容格式

```
"[方法名] 描述: {ParamName}", ParamValue
```

示例：
```csharp
_logger.LogInformation("[CalculateOffset] 输入: point={Point}, config={Config}", point, config);
_logger.LogInformation("[CalculateOffset] 分支: 使用线性插值, factor={Factor}", factor);
_logger.LogInformation("[CalculateOffset] 结果: offset={Offset}", offset);
```

### 注入位置（按优先级）

1. **方法入口** — 记录所有输入参数
2. **条件分支** — 记录走了哪个分支及关键判断值
3. **计算/转换结果** — 记录中间结果和最终返回值
4. **循环体** — 记录迭代索引和每次迭代的中间值（仅在循环体较复杂时）
5. **外部调用前后** — 记录调用参数和返回值
6. **catch 块** — 补充异常上下文信息

### 注意事项

- 不修改任何业务逻辑，只添加日志语句
- 日志消息以方法名开头，方便 grep 过滤
- 用结构化日志参数 `{Name}` 而非字符串插值 `$""`
- 如果方法已存在足够的诊断日志，跳过不重复添加
- 对于简单的属性 getter/setter 或无逻辑的透传方法，不加日志

## 执行步骤

1. 分析输入，确定涉及的代码文件和方法
2. 读取相关源文件，理解执行流程
3. 按上述规则在每个关键位置注入日志
4. 汇总报告：修改了哪些文件、哪些方法、加了什么级别的日志
5. 提示用户下一步：编译 → 运行 → 复现问题 → 收集日志输出

## 输出格式

完成后输出简要总结：

```
已注入诊断日志：
- FileA.cs::MethodX — 入口参数 + 分支判断 (Info)
- FileA.cs::MethodY — 循环迭代值 (Info) + 异常上下文 (Error)
- FileB.cs::MethodZ — 外部调用前后 (Info)

下一步：编译项目，运行并复现问题，然后用日志输出继续定位。
```

