# 第八阶段 · 模块八 · 第一节:日志系统架构
Claude Code 的日志系统是如何设计的?日志存储在哪里?如何读取和分析日志?
Claude Code 全局架构
┌─────────────────────────────────────────────────────────────────────┐
│ 调试与日志 ← 本节 │
│ │
│ 日志系统架构 │
│ ├── logError ──> 错误日志 │
│ ├── logEvent ──> 事件日志 │
│ └── 日志存储 ──> ~/.claude/logs │
└─────────────────────────────────────────────────────────────────────┘
// Claude Code 日志类型:
// 1. 错误日志
// - logError()
// - 记录异常和错误
// - 位置:~/.claude/logs/errors/
// 2. 事件日志
// - logEvent()
// - 记录重要事件
// - 位置:~/.claude/logs/events/
// 3. 调试日志
// - logForDebugging()
// - 仅在 --verbose 模式启用
// - 位置:~/.claude/debug/latest
// 源码位置:src/utils/log.ts
const LOG_PATHS = {
errors: '~/.claude/logs/errors',
events: '~/.claude/logs/events',
debug: '~/.claude/debug/latest',
sessions: '~/.claude/logs/sessions',
};
问 1:日志默认开启吗?
// 错误日志:始终开启
logError('Something went wrong');
// 事件日志:需要配置
logEvent({ type: 'tool_call', data: ... });
// 调试日志:仅 --verbose 模式
claude --verbose
源码位置:`src/utils/log.ts` 第 158 行
export function logError(error: unknown): void {
const err = toError(error);
// 检查是否禁用错误报告
if (isEnvTruthy(process.env.DISABLE_ERROR_REPORTING)) {
return;
}
const errorInfo = {
error: err.stack || err.message,
timestamp: new Date().toISOString(),
};
// 添加到内存日志
addToInMemoryErrorLog(errorInfo);
// 写入文件
errorLogSink.logError(err);
}
// 错误类型:
interface ErrorInfo {
error: string; // 错误消息
timestamp: string; // 时间戳
sessionId?: string; // 会话 ID
context?: string; // 错误上下文
}
// 常见错误类型:
// - APIError:API 调用错误
// - ToolError:工具执行错误
// - AuthError:认证错误
// - NetworkError:网络错误
问 1:HARD FAIL 模式是什么?
// 源码位置:log.ts 第 154 行
const isHardFailMode = (): boolean => {
return process.argv.includes('--hard-fail');
};
// 启用后,任何 logError 调用都会导致程序退出
if (isHardFailMode()) {
console.error('[HARD FAIL] logError called');
process.exit(1);
}
interface LogEvent {
type: string; // 事件类型
timestamp: string; // 时间戳
data: unknown; // 事件数据
sessionId?: string; // 会话 ID
}
// 事件类型示例
const EVENT_TYPES = {
SESSION_START: 'session_start',
SESSION_END: 'session_end',
TOOL_CALL: 'tool_call',
TOOL_RESULT: 'tool_result',
COMMAND: 'command',
MODEL_CHANGE: 'model_change',
};
{
"type": "tool_call",
"timestamp": "2026-04-02T10:30:00.000Z",
"sessionId": "abc123",
"data": {
"tool": "Read",
"input": { "file_path": "a.txt" }
}
}
问 1:事件日志有什么用?
// 1. 问题排查
// 查看特定事件的完整上下文
// 2. 性能分析
// 分析工具调用频率和耗时
// 3. 使用统计
// 了解用户使用模式
export function logForDebugging(
message: string,
context?: Record<string, unknown>,
): void {
if (!isVerboseMode()) {
return;
}
const entry = {
timestamp: new Date().toISOString(),
message,
context,
};
console.log('[DEBUG]', JSON.stringify(entry, null, 2));
}
# 启用调试模式
claude --verbose
# 或
claude --debug
# 查看实时调试日志
tail -f ~/.claude/debug/latest
问 1:verbose 和 debug 的区别?
// --verbose:详细输出
// - 显示所有调试信息
// - 包括 API 请求/响应
// --debug:调试模式
// - 更详细的调试信息
// - 包括堆栈跟踪
# 查看最近错误
ls -la ~/.claude/logs/errors/
# 查看特定会话
cat ~/.claude/logs/sessions/<session-id>.json
# 搜索错误
grep -r "Error" ~/.claude/logs/errors/
// 内置日志分析
claude logs analyze
// 输出:
// - 错误统计
// - 工具使用频率
// - API 调用次数
// - 平均响应时间
问 1:日志保留多久?
// 日志保留策略
const LOG_RETENTION = {
errors: '90 days', // 错误日志保留 90 天
events: '30 days', // 事件日志保留 30 天
debug: '7 days', // 调试日志保留 7 天
sessions: '180 days', // 会话日志保留 180 天
};
答案:
# 1. 开启调试模式
claude --verbose
# 2. 复现问题
# 执行出错的操作
# 3. 查看日志
tail -f ~/.claude/debug/latest
# 4. 搜索相关错误
grep -A5 "ToolError" ~/.claude/logs/errors/*
答案:
// Claude Code 会过滤敏感信息
const SENSITIVE_PATTERNS = [
'password',
'api_key',
'secret',
'token',
];
function filterSensitiveData(log: Record<string, unknown>): Record<string, unknown> {
for (const [key, value] of Object.entries(log)) {
if (SENSITIVE_PATTERNS.some(p => key.toLowerCase().includes(p))) {
log[key] = '[REDACTED]';
}
}
return log;
}
答案:
# 1. 收集日志
claude logs export --output bug-report.zip
# 2. 创建 Issue
# 附上日志文件和复现步骤
# 3. 匿名报告
# 如果使用匿名模式,日志会自动脱敏
| 文件 | 核心内容 |
| `src/utils/log.ts` | 日志系统核心 |
| `src/types/logs.ts` | 日志类型定义 |
下一节我们将深入 调试模式详解:
- --verbose 和 --debug 的区别
- 实时调试技巧
- 常见问题诊断
*- 第一轮:□ 事实准确性*
*- 第二轮:□ 深度与洞见*
*- 第三轮:□ 可读性与价值*