日志检查Skill log-inspection

日志检查技能用于查询和分析钩子事件日志,支持会话列表、时间线、统计等功能,方便开发者进行日志管理和性能监控。关键词:日志检查、数据分析、DevOps、钩子事件、性能监控、日志查询。

DevOps 0 次安装 0 次浏览 更新于 3/11/2026

名称: 日志检查 描述: 检查和查询钩子事件日志。子命令: sessions, timeline, trace, agents, team, stats, coverage, daily. 用户可调用: true 参数提示: “<子命令> [选项]” 允许工具: Read, Bash, Glob, Grep

日志检查

从 JSONL 文件中查询和检查可观测性钩子日志。

参数

子命令是第一个参数:

  • sessions – 列出所有会话,包括事件计数和持续时间
  • timeline [session-id] – 按时间顺序显示事件列表,带有序列号
  • trace <tool-use-id> – 显示工具调用的前后配对
  • agents – 子代理生命周期(启动/停止/持续时间)
  • team – 队友闲置和任务完成活动
  • stats – 聚合统计(事件分解、工具使用、损坏计数)
  • coverage – 观察到的 14 种事件类型
  • daily – 从 sessions-index.jsonl 显示每日摘要(v1.6.0)

日志文件位置

在以下位置查找日志文件:

{项目}/.claude/logs/hooks/events-{YYYY-MM-DD}.jsonl
{项目}/.claude/logs/hooks/events-{YYYY-MM-DD}.jsonl.gz  (压缩的冷日志)

使用 Glob 查找所有可用的日志文件:

Glob(".claude/logs/hooks/events-*.jsonl")
Glob(".claude/logs/hooks/events-*.jsonl.gz")

注意: 超过 7 天的文件会自动压缩为 .jsonl.gz(可通过 CLAUDE_HOOK_LOG_COMPRESS_AFTER_DAYS 配置)。DuckDB 原生读取 .jsonl.gz;在 Unix 上使用 zcat | jq 进行手动检查。

工作流程

步骤 1: 定位日志文件

在项目中查找所有钩子日志文件:

Glob(".claude/logs/hooks/events-*.jsonl")
Glob(".claude/logs/hooks/events-*.jsonl.gz")
Glob(".claude/logs/hooks/sessions-index.jsonl")

如果日志文件不存在,通知用户必须通过 CLAUDE_HOOK_LOG_EVENTS_ENABLED=1 启用日志记录。

步骤 2: 执行子命令

sessions

如果存在,解析 sessions-index.jsonl。使用 type 字段区分条目(session_start, session_end, agent_start, agent_stop)。为了向后兼容,没有 type 的条目根据 started_at(session_start)或 ended_at(session_end)的存在进行推断。否则,扫描事件日志文件中的 sessionstartsessionend 事件。显示:

会话 ID 开始时间 结束时间 模型 事件数 持续时间

增强的索引还包括 cwd, transcript_path, model, 和 agent_type 在 session_start 条目上。

timeline [session-id]

读取日志文件并按序列顺序显示事件。如果提供 session-id,则过滤到该会话。显示:

序列号  时间戳               事件             工具名称   进程ID
1    2026-02-15T18:13:23  sessionstart       -            12345
2    2026-02-15T18:13:24  userpromptsubmit   -            12345
3    2026-02-15T18:13:25  pretooluse         Read         12346
4    2026-02-15T18:13:25  posttooluse        Read         12346

trace <tool-use-id>

找到具有给定 tool_use_id 的 pretooluse 和 posttooluse/posttoolusefailure 条目。显示配对,展示时间和成功/失败。

agents

首先检查 sessions-index.jsonl 中的 agent_startagent_stop 条目(直接查找,无需事件扫描)。如果索引缺失,则回退到扫描事件日志文件中的 subagentstartsubagentstop 事件。显示:

代理 ID 类型 开始时间(序列) 停止时间(序列) 持续时间

team

首先检查 sessions-index.jsonl 中的 task_completedteammate_idle 条目(v1.8.0 添加的直接查找)。如果索引条目缺失,则回退到扫描事件日志文件中的 teammateidletaskcompleted 事件。显示:

时间 类型 队友 团队 任务主题

stats

解析所有条目并计算:

  • 事件分解: 每种事件类型的计数
  • 工具使用: 最频繁使用的工具(从 pretooluse 事件)
  • 错误率: posttoolusefailure 计数 / 总工具使用次数
  • 平均持续时间_ms: 平均钩子处理时间
  • 损坏计数: JSON 解析失败的行数
  • 唯一会话数: 不同 session_id 值的计数
  • 序列范围: 最小和最大序列值

使用带有 Python 单行命令的 Bash 进行聚合。对于 .jsonl.gz 文件,使用 gzip.open 读取:

python3 -c "
import json, gzip, glob
from collections import Counter
events = Counter()
tools = Counter()
errors = 0
corrupt = 0
durations = []
sessions = set()

def read_lines(path):
    if path.endswith('.gz'):
        with gzip.open(path, 'rt', encoding='utf-8') as f:
            return f.readlines()
    with open(path, 'r', encoding='utf-8') as f:
        return f.readlines()

for path in sorted(glob.glob('.claude/logs/hooks/events-*.jsonl') + glob.glob('.claude/logs/hooks/events-*.jsonl.gz')):
    for line in read_lines(path):
        line = line.strip()
        if not line:
            continue
        try:
            e = json.loads(line)
            events[e.get('event','')] += 1
            if 'tool_name' in e:
                tools[e['tool_name']] += 1
            if e.get('event') == 'posttoolusefailure':
                errors += 1
            durations.append(e.get('duration_ms', 0))
            sessions.add(e.get('session_id',''))
        except json.JSONDecodeError:
            corrupt += 1
print(f'事件: {dict(events)}')
print(f'顶部工具: {tools.most_common(10)}')
print(f'错误率: {errors}/{events.get(\"pretooluse\",0)} 工具使用次数')
print(f'平均持续时间: {sum(durations)/len(durations):.2f}ms' if durations else '无条目')
print(f'损坏行数: {corrupt}')
print(f'唯一会话数: {len(sessions)}')
"

注意: hook_event_name 在 v1.4.0 中从条目中移除,并在 v1.7.0 中从 extra_fields 中完全抑制。

coverage

检查已捕获的 14 种事件类型。显示:

事件覆盖率报告
=====================
[x] pretooluse (142 事件)
[x] posttooluse (140 事件)
[x] userpromptsubmit (8 事件)
[ ] precompact (0 事件)
...
覆盖率: 12/14 事件类型已观察

14 种必需类型是: pretooluse, posttooluse, posttoolusefailure, permissionrequest, notification, userpromptsubmit, stop, subagentstart, subagentstop, precompact, sessionstart, sessionend, teammateidle, taskcompleted.

daily

解析 sessions-index.jsonl 中的 daily_summary 条目(v1.6.0)。显示:

日期 事件数 会话数 错误数 平均持续时间

每日摘要每天在第一个 sessionstart 时自动生成,基于前一天的日志。

步骤 3: 格式化输出

以清晰、可读的格式呈现结果。适当时使用 Markdown 表格。在标题中包含日志文件路径和日期范围。

DuckDB 查询(高级)

对于大型日志文件,建议使用 DuckDB 进行分析查询:

-- 直接加载 JSONL
SELECT event, count(*) as cnt
FROM read_json_auto('.claude/logs/hooks/events-2026-02-15.jsonl')
GROUP BY event ORDER BY cnt DESC;

-- 工具使用时序
SELECT tool_name, count(*) as uses, avg(duration_ms) as avg_ms
FROM read_json_auto('.claude/logs/hooks/events-2026-02-15.jsonl')
WHERE event = 'pretooluse'
GROUP BY tool_name ORDER BY uses DESC;

-- 查找损坏条目(序列间隙)
SELECT seq, lag(seq) OVER (ORDER BY seq) as prev_seq
FROM read_json_auto('.claude/logs/hooks/events-2026-02-15.jsonl')
WHERE seq - lag(seq) OVER (ORDER BY seq) > 1;

使用示例

# 列出会话
/claude-code-observability:log-inspection sessions

# 当前会话的时间线
/claude-code-observability:log-inspection timeline

# 跟踪特定工具调用
/claude-code-observability:log-inspection trace toolu_01abc123

# 事件类型覆盖率
/claude-code-observability:log-inspection coverage

# 完整统计
/claude-code-observability:log-inspection stats