maycur-ai-log-analyzer — 日志分析
链路第二环:消费 clue/clue.md 的查询条件,调度 slser + langfuse skill 查日志/trace,产出 logs/*.json 供下游 code-analyzer / root-cause-analyzer 消费。
Claude vs 脚本分工
| 角色 | 职责 |
|---|---|
| Claude | 读 clue.md 提取条件;调度 langfuse skill/slser 查询(结果存临时文件);调 collect_logs.py 组装 |
| collect_logs.py | 读 clue.md + 查询结果文件 → 组装 logs/*.json(query_conditions + discovered_trace_ids + raw_data)。不调 API |
查询单一路径
路径 A:clue.md 有 traceId
① langfuse skill 按 traceId 查(官方 langfuse-cli,凭据经凭证 CLI 导出):
eval "$(python -m scripts.credentials env langfuse)"
npx -y langfuse-cli --api-version 3.150.0 api traces get <traceId>
npx -y langfuse-cli --api-version 3.150.0 api observations list --trace-id <traceId> --limit 100
注:maycur 自托管 Langfuse 3.x 必须固定 --api-version 3.150.0(默认 4.10.0 快照
封锁 legacy traces 端点,v2 observations 仅 Cloud beta);traces get 用位置参数。
→ 结果存 <tmp>/langfuse_raw.json
② slser 按 traceId 查 SLS:
python skills/slser/scripts/sls_query.py query --project <P> --logstore <L> \
--query "<traceId>" --range <from>/<to>
→ 结果存 <tmp>/sls_raw.json
③ collect_logs.py 组装两份物料
路径 B:clue.md 无 traceId
① slser 按 entCode+单据号+异常关键字+时间窗查:
python skills/slser/scripts/sls_query.py query --project <P> --logstore <L> \
--query "<entCode> and <单据号> and <异常关键字>" --range <from>/<to>
→ 结果存 <tmp>/sls_raw.json
② collect_logs.py 从 SLS 结果提取 discovered_trace_ids(自动)
③ 若 discovered_trace_ids 非空:
→ Claude 取第一个 traceId 按路径 A ① 的 langfuse-cli 命令查询
→ langfuse 物料有数据
若为空:
→ langfuse 物料 row_count=0(无 LLM 调用链)
④ collect_logs.py 组装两份物料
SLS project/logstore 发现
Claude 读 clue.md 的 环境 字段 → 调 slser skill 列项目/logstore(动态发现,不预设环境→资源映射)→ AskUserQuestion 让用户选。若 clue.md 没环境字段,直接问用户。
collect_logs.py 调用
编排模式(bug-killer 调度,读 clue.md):
python <skill-dir>/scripts/collect_logs.py \
--clue <bug_dir>/clue/clue.md \
--langfuse-result <tmp>/langfuse_raw.json \
--sls-result <tmp>/sls_raw.json \
--output-dir <bug_dir>/logs
独立模式(用户单独调用,直接给查询条件):
python <skill-dir>/scripts/collect_logs.py \
--conditions '{"trace_id":"","ent_code":"EC1","bill_no":"BX1","env":"prod","keywords":["NPE"],"time_window":{"from":"...","to":"..."}}' \
--sls-result <tmp>/sls_raw.json \
--output-dir ./logs
--langfuse-result / --sls-result 都可选(某路径无数据时省略,raw_data 自动为空)。
执行流程
- 探测
{bug_dir}/clue/clue.md:- 存在 → 编排模式
- 不存在 → 独立模式(AskUserQuestion 收集 traceId/entCode/环境/时间窗/异常关键字)
- 从 clue.md(或用户输入)获取 query_conditions
- 判断路径:traceId 非空 → 路径 A;traceId 为空 → 路径 B
- 执行查询(调度 langfuse + slser,结果存临时文件)
- 调 collect_logs.py 组装物料
- 物料生成完毕,流程结束
物料产出
两份 JSON,统一 schema:
{
"query_conditions": {
"trace_id": "...", "ent_code": "...", "bill_no": "...",
"env": "...", "keywords": [...],
"time_window": { "from": "...", "to": "..." }
},
"discovered_trace_ids": ["从日志提取的 traceId 去重列表"],
"row_count": 42,
"raw_data": [ ... 原始查询结果 ... ]
}
logs/langfuse-trace.json:Langfuse trace 数据(discovered_trace_ids 为空,本身按 traceId 查)logs/sls-logs.json:SLS 日志数据(discovered_trace_ids 从日志内容正则提取)
边界
- 不做 clue 信息收集(bug-clue-analyzer 职责)
- 不做代码分析(code-analyzer 职责)
- 不做根因综合(root-cause-analyzer 职责)
- 不做 A/B/C/D 多路径(单一路径)
- collect_logs.py 不调 API(Claude 调度查询)
依赖
- slser(
sls_query.py):SLS 日志查询(query 子命令) - langfuse skill(官方,用户级安装,不在本仓库):Langfuse trace 查询(
npx langfuse-cli --api-version 3.150.0,凭据经python -m scripts.credentials env langfuse导出) - collect_logs.py(自带脚本):物料组装