with one click
workflow-logging
工作流过程日志格式规范和写入模式。定义 JSONL 和文本两种格式的日志结构、事件类型、级别定义和写入方法。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
工作流过程日志格式规范和写入模式。定义 JSONL 和文本两种格式的日志结构、事件类型、级别定义和写入方法。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
master-coordinator 和 review-coordinator 共享的通用模式,包括 Phase 验证、错误处理、TodoWrite 管理和状态说明。所有 coordinator agents 应引用此 skill 以保持一致性。
计划执行工作流知识库,包含计划格式规范、任务解析、依赖分析和执行策略
Strunk 写作规则,用于提升文档质量。适用于所有面向人类读者的文本:文档、报告、注释、提交信息等。
PR Review 修复模式库。在处理 PR Review 评论时自动查阅,寻找已知问题模式和解决方案。
通用 Bugfix 工作流知识库,包含 TDD 流程、输出格式规范、置信度评分标准和通用最佳实践。适用于所有技术栈(backend/frontend/e2e)。
CI Job 失败分析知识库,包含失败类型分类、置信度评估、技术栈识别和常见错误模式
Based on SOC occupation classification
| name | workflow-logging |
| description | 工作流过程日志格式规范和写入模式。定义 JSONL 和文本两种格式的日志结构、事件类型、级别定义和写入方法。 |
本规范定义了 Swiss Army Knife 插件所有工作流的日志格式和写入模式。
| 级别 | 代码 | 用途 |
|---|---|---|
| INFO | I | 正常流程事件(Phase/Agent 开始结束) |
| DEBUG | D | 详细调试信息(完整 agent I/O,仅 --verbose) |
| WARN | W | 可恢复的警告(如 Git 不可用) |
| ERROR | E | 错误和失败 |
| DECISION | X | 决策点(置信度决策、用户交互) |
| 类型 | 说明 | 时机 |
|---|---|---|
| SESSION_START | 会话开始 | 工作流初始化后 |
| SESSION_END | 会话结束 | 工作流完成或失败后 |
| 类型 | 说明 | 时机 |
|---|---|---|
| PHASE_START | Phase 开始 | 每个 Phase 执行前 |
| PHASE_END | Phase 结束 | 每个 Phase 完成后 |
| 类型 | 说明 | 时机 |
|---|---|---|
| AGENT_CALL | Agent 调用 | Task 工具调用前 |
| AGENT_RESULT | Agent 返回 | Task 工具返回后 |
| 类型 | 说明 | 时机 |
|---|---|---|
| STEP_START | 步骤开始 | Agent 内部每个主要步骤开始 |
| STEP_END | 步骤结束 | Agent 内部每个主要步骤结束 |
| TOOL_USE | 工具调用 | Agent 使用 Read/Bash/Glob 等工具 |
| DATA_COLLECTED | 数据收集 | 关键数据收集完成(配置、测试输出等) |
| ANALYSIS_RESULT | 分析结果 | 错误分类、根因分析等结果 |
| 类型 | 说明 | 时机 |
|---|---|---|
| CONFIDENCE_DECISION | 置信度决策 | 根因分析等置信度检查点 |
| USER_INTERACTION | 用户交互 | AskUserQuestion 调用 |
| 类型 | 说明 | 时机 |
|---|---|---|
| REVIEW_PARALLEL_START | 并行审查开始 | 6 个 review agents 启动 |
| REVIEW_PARALLEL_END | 并行审查结束 | 6 个 agents 全部返回 |
| REVIEW_FIX_ITERATION | Fix 循环迭代 | 每次 review-fix 循环 |
| 类型 | 说明 | 时机 |
|---|---|---|
| WARNING | 警告信息 | 可恢复的问题 |
| ERROR | 错误信息 | 失败和异常 |
每行一条完整的 JSON 记录,字段定义:
{
"ts": "YYYY-MM-DDTHH:MM:SS.000Z", // ISO 8601 时间戳(必填)
"level": "I", // 日志级别(必填)
"type": "PHASE_START", // 事件类型(必填)
"session_id": "a1b2c3d4" // 会话 ID(必填)
}
注意:以下示例中的时间戳仅为演示,实际使用时应替换为当前时间。
{
"ts": "2024-12-06T14:30:52.123Z",
"level": "I",
"type": "SESSION_START",
"session_id": "a1b2c3d4",
"workflow": "bugfix",
"stack": "frontend",
"command": "/swiss-army-knife:fix-frontend --log",
"args": {
"phase": "all",
"dry_run": false,
"log": true,
"verbose": false
},
"env": {
"project_root": "/path/to/project",
"plugin_version": "1.0.0",
"git_branch": "feature/login"
}
}
{
"ts": "2024-12-06T14:40:00.000Z",
"level": "I",
"type": "SESSION_END",
"session_id": "a1b2c3d4",
"status": "success",
"total_duration_ms": 548000,
"phases_completed": ["phase_0", "phase_1", "phase_2", "phase_3", "phase_4", "phase_5"],
"summary": {
"errors_fixed": 3,
"files_changed": 2,
"review_issues_fixed": 4,
"user_interactions": 2
}
}
{
"ts": "2024-12-06T14:30:53.456Z",
"level": "I",
"type": "PHASE_START",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"phase_name": "问题收集与分类",
"agents": ["frontend-init-collector", "frontend-error-analyzer"]
}
{
"ts": "2024-12-06T14:31:05.789Z",
"level": "I",
"type": "PHASE_END",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"status": "success",
"duration_ms": 12333,
"summary": {
"errors_found": 3,
"test_status": "test_failed"
}
}
{
"ts": "2024-12-06T14:30:53.500Z",
"level": "I",
"type": "AGENT_CALL",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"model": "sonnet",
"input_summary": "加载配置和收集测试输出"
}
{
"ts": "2024-12-06T14:30:58.200Z",
"level": "I",
"type": "AGENT_RESULT",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"status": "success",
"duration_ms": 4700,
"output_summary": {
"config_loaded": true,
"test_output_lines": 150,
"warnings_count": 1
}
}
{
"ts": "2024-12-06T14:30:54.000Z",
"level": "I",
"type": "STEP_START",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"step": "config_loading",
"step_name": "加载配置",
"step_index": 1,
"total_steps": 3
}
{
"ts": "2024-12-06T14:30:55.500Z",
"level": "I",
"type": "STEP_END",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"step": "config_loading",
"status": "success",
"duration_ms": 1500,
"result_summary": {
"default_config": true,
"project_config": true,
"merged": true
}
}
{
"ts": "2024-12-06T14:30:54.200Z",
"level": "D",
"type": "TOOL_USE",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"step": "config_loading",
"tool": "Read",
"target": "config/defaults.yaml",
"status": "success"
}
{
"ts": "2024-12-06T14:30:56.000Z",
"level": "I",
"type": "DATA_COLLECTED",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"data_type": "test_output",
"summary": {
"lines": 150,
"exit_code": 1,
"status": "test_failed",
"source": "auto_run"
}
}
{
"ts": "2024-12-06T14:31:02.000Z",
"level": "I",
"type": "ANALYSIS_RESULT",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-error-analyzer",
"analysis_type": "error_classification",
"result": {
"errors_found": 3,
"categories": {
"mock_conflict": 2,
"async_timing": 1
},
"files_affected": ["Button.test.tsx", "Form.test.tsx"]
}
}
{
"ts": "2024-12-06T14:31:15.100Z",
"level": "X",
"type": "CONFIDENCE_DECISION",
"session_id": "a1b2c3d4",
"phase": "phase_1",
"confidence_score": 65,
"threshold": {
"auto_continue": 60,
"ask_user": 40,
"stop": 0
},
"decision": "auto_continue",
"factors": {
"clarity": 70,
"specificity": 60,
"context": 65,
"reproducibility": 55
}
}
{
"ts": "2024-12-06T14:32:00.000Z",
"level": "X",
"type": "USER_INTERACTION",
"session_id": "a1b2c3d4",
"phase": "phase_3",
"interaction_type": "AskUserQuestion",
"question": "Bugfix 方案已生成,请查看 docs/bugfix/xxx.md。确认后开始实施。",
"options": ["确认执行", "调整方案", "取消"],
"user_response": "确认执行",
"wait_duration_ms": 15000
}
{
"ts": "2024-12-06T14:35:00.000Z",
"level": "I",
"type": "REVIEW_PARALLEL_START",
"session_id": "a1b2c3d4",
"phase": "phase_5",
"agents": [
"review-code-reviewer",
"review-silent-failure-hunter",
"review-code-simplifier",
"review-test-analyzer",
"review-comment-analyzer",
"review-type-design-analyzer"
]
}
{
"ts": "2024-12-06T14:35:30.000Z",
"level": "I",
"type": "REVIEW_PARALLEL_END",
"session_id": "a1b2c3d4",
"phase": "phase_5",
"duration_ms": 30000,
"results": [
{"agent": "review-code-reviewer", "status": "success", "issues": 2},
{"agent": "review-silent-failure-hunter", "status": "success", "issues": 1},
{"agent": "review-code-simplifier", "status": "success", "issues": 0},
{"agent": "review-test-analyzer", "status": "success", "issues": 1},
{"agent": "review-comment-analyzer", "status": "failed", "error": "timeout"},
{"agent": "review-type-design-analyzer", "status": "success", "issues": 0}
],
"total_issues": 4,
"fixable_issues": 3
}
{
"ts": "2024-12-06T14:36:00.000Z",
"level": "I",
"type": "REVIEW_FIX_ITERATION",
"session_id": "a1b2c3d4",
"phase": "phase_5",
"iteration": 1,
"issues_before": 4,
"issues_after": 1,
"fixed_count": 3,
"termination_reason": null
}
{
"ts": "2024-12-06T14:31:10.500Z",
"level": "W",
"type": "WARNING",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"code": "GIT_UNAVAILABLE",
"message": "Git 信息收集失败:not a git repository",
"impact": "根因分析将缺少版本控制上下文"
}
{
"ts": "2024-12-06T14:33:00.000Z",
"level": "E",
"type": "ERROR",
"session_id": "a1b2c3d4",
"phase": "phase_1",
"code": "CONFIDENCE_TOO_LOW",
"message": "根因分析置信度 35% 低于阈值 40%",
"agent": "frontend-root-cause",
"recoverable": false
}
{
"ts": "2024-12-06T14:30:53.500Z",
"level": "D",
"type": "AGENT_IO",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"agent": "frontend-init-collector",
"direction": "input",
"content": "... 完整的 agent 输入 ..."
}
人类可读的时间线格式,每行一条记录:
[{timestamp}] {LEVEL} | {TYPE} | {message}
[2024-12-06 14:30:52.123] INFO | SESSION_START | Bugfix Frontend (a1b2c3d4)
[2024-12-06 14:30:52.123] INFO | ENV | project=/path/to/project branch=feature/login
[2024-12-06 14:30:53.456] INFO | PHASE_START | Phase 0: 问题收集与分类
[2024-12-06 14:30:53.500] INFO | AGENT_CALL | frontend-init-collector (sonnet)
[2024-12-06 14:30:58.200] INFO | AGENT_RESULT | frontend-init-collector | success | 4700ms
[2024-12-06 14:31:05.789] INFO | PHASE_END | Phase 0 | success | 12333ms | errors_found=3
[2024-12-06 14:31:06.000] INFO | PHASE_START | Phase 1: 诊断分析
[2024-12-06 14:31:15.100] DECN | CONFIDENCE | score=65 | decision=auto_continue | threshold=60
[2024-12-06 14:31:20.000] INFO | PHASE_END | Phase 1 | success | 14000ms
[2024-12-06 14:32:00.000] DECN | USER_ASK | "确认后开始实施" | options=[确认执行,调整方案,取消]
[2024-12-06 14:32:15.000] DECN | USER_ANSWER | "确认执行" | wait=15000ms
[2024-12-06 14:35:00.000] INFO | REVIEW_START | 6 agents: code-reviewer,silent-failure-hunter,...
[2024-12-06 14:35:30.000] INFO | REVIEW_END | 30000ms | issues=4 | fixable=3
[2024-12-06 14:36:00.000] INFO | REVIEW_FIX | iteration=1 | before=4 | after=1 | fixed=3
[2024-12-06 14:40:00.000] INFO | SESSION_END | success | 548000ms | files=2 | issues_fixed=4
INFO - 正常信息(4 字符 + 空格)
DEBUG - 调试信息(5 字符)
WARN - 警告(4 字符 + 空格)
ERROR - 错误(5 字符)
DECN - 决策(4 字符 + 空格)
由于 Write 工具会覆盖文件,必须使用 Bash 追加:
# JSONL 格式
echo '{"ts":"2024-12-06T14:30:52.123Z","level":"I","type":"PHASE_START",...}' >> "${jsonl_file}"
# 文本格式
echo '[2024-12-06 14:30:52.123] INFO | PHASE_START | Phase 0: 问题收集与分类' >> "${log_file}"
JSON 字符串中的特殊字符需要正确转义:
" → \"\ → \\\n2024-12-06T14:30:52.123Z[2024-12-06 14:30:52.123]获取当前时间戳:
# ISO 8601 格式(用于 JSONL)
date -u +"%Y-%m-%dT%H:%M:%S.000Z"
# 人类可读格式(用于文本)
date +"%Y-%m-%d %H:%M:%S.000"
命令层传递给 coordinator 的 logging 上下文:
{
"logging": {
"enabled": true,
"level": "info",
"session_id": "a1b2c3d4"
}
}
Master Coordinator 初始化日志文件后,传递给每个 Phase Agent:
{
"logging": {
"enabled": true,
"level": "info",
"session_id": "a1b2c3d4",
"phase": "phase_0",
"log_files": {
"jsonl": ".claude/logs/swiss-army-knife/bugfix/2024-12-06_143052_frontend_a1b2c3d4.jsonl",
"text": ".claude/logs/swiss-army-knife/bugfix/2024-12-06_143052_frontend_a1b2c3d4.log"
}
}
}
Phase Agent 收到 logging 上下文后,在每个主要步骤记录日志:
## 日志记录
如果 `logging.enabled` 为 `true`,在每个步骤记录日志:
### 步骤开始
\`\`\`bash
# JSONL
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"STEP_START","session_id":"${session_id}","phase":"${phase}","agent":"${agent_name}","step":"config_loading","step_name":"加载配置","step_index":1,"total_steps":3}' >> "${jsonl_file}"
# 文本
echo "[$(date +"%Y-%m-%d %H:%M:%S.000")] INFO | STEP_START | ${agent_name} | 步骤 1/3: 加载配置" >> "${log_file}"
\`\`\`
### 步骤结束
\`\`\`bash
# JSONL
echo '{"ts":"'$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")'","level":"I","type":"STEP_END","session_id":"${session_id}","phase":"${phase}","agent":"${agent_name}","step":"config_loading","status":"success","duration_ms":1500}' >> "${jsonl_file}"
# 文本
echo "[$(date +"%Y-%m-%d %H:%M:%S.000")] INFO | STEP_END | ${agent_name} | 步骤 1/3 完成 | 1500ms" >> "${log_file}"
\`\`\`
Coordinator 初始化后计算日志文件路径:
log_dir = ".claude/logs/swiss-army-knife/{workflow}"
timestamp = "2024-12-06_143052"
session_id = input.logging.session_id
jsonl_file = f"{log_dir}/{timestamp}_{identifier}_{session_id}.jsonl"
log_file = f"{log_dir}/{timestamp}_{identifier}_{session_id}.log"
{
"logging": {
"enabled": true,
"level": "info",
"session_id": "a1b2c3d4",
"log_files": {
"jsonl": ".claude/logs/swiss-army-knife/bugfix/xxx.jsonl",
"text": ".claude/logs/swiss-army-knife/bugfix/xxx.log"
}
}
}
# 查看会话摘要
jq 'select(.type == "SESSION_START" or .type == "SESSION_END")' xxx.jsonl
# 查看所有错误
jq 'select(.level == "E")' xxx.jsonl
# 查看 Phase 耗时
jq 'select(.type == "PHASE_END") | {phase, duration_ms, status}' xxx.jsonl
# 查看置信度决策
jq 'select(.type == "CONFIDENCE_DECISION")' xxx.jsonl
# 查看用户交互
jq 'select(.type == "USER_INTERACTION")' xxx.jsonl
# 按时间排序
jq -s 'sort_by(.ts)' xxx.jsonl
# 计算总耗时
jq 'select(.type == "SESSION_END") | .total_duration_ms / 1000 | "\(.) 秒"' xxx.jsonl
# 查看所有错误
grep "ERROR" xxx.log
# 查看 Phase 耗时
grep "PHASE_END" xxx.log
# 查看决策点
grep "DECN" xxx.log
# 查看特定 agent
grep "frontend-root-cause" xxx.log