Skip to content

09. 日志记录和可观测性

翻译说明: 本页是与 英文源规格 一一对应的机器辅助翻译。代码、协议字段和标识符保持原文;如翻译与英文源事实有歧义,以英文版本为准。

1. 目标

1.快速诊断故障 2. 审核敏感的 tool/plugin 操作 3.避免泄露秘密 4. 保持 MVP 简单(本地文件优先)

2. 日志级别

  • debug
  • info
  • warn
  • error

默认运行时级别:

  • 开发者:debug
  • 发布:info

3. 渠道

频道内容位置
应用程序启动、ipc、窗口、进程监控~/.pi-desktop/logs/app/<category>.log
主机rust host-core 事件(stderr 捕获)~/.pi-desktop/logs/host/<category>.log
代理人pi sidecar turn/provider 事件(stderr 捕获)~/.pi-desktop/logs/agent/<category>.log
审计permissions/tools/plugins 敏感操作host-core SQLite audit_log
插件每个插件的日志~/.pi-desktop/plugins/logs/<id>.log

注意事项:

  • tool/plugin/MVP/debug 是 Electron 主程序写入的 NDJSON 文件 Loggerapps/desktop/electron/main/logger.ts); host/agent stderr 行 被打包到他们频道的记录中。
  • 审核通道存储在 SQLite(归 host-core、D006 所有)中,而不是 平面文件:它需要可查询性和比调试日志更长的保留时间。 logs folder 诊断仍然适用于三个文件通道。

3a。类别路由

三个进程通道是目录,而不是聚合文件。主要 进程将每条记录写入 <channel>/<category>.log,因此大容量 可以独立检查会话、工具、计时和提供商记录。

应用程序渠道使用以下类别:

  • lifecycle — 启动、关闭和应用程序监控
  • session — 提示、回合、会话生命周期和压缩
  • tool — 工具 start/end 事件
  • permission — 权限请求和决定
  • plugin — 插件加载、服务和插件工具执行
  • provider — provider/model 发现和缓存失败
  • persistence — 成绩单和发件箱持久性失败
  • updater — 电子更新器诊断
  • diagnostics — 阻止导航、菜单和模板诊断
  • terminal — 终端附件
  • runtime — host/sidecar 生命周期事件

主机和代理stderr在线路时被归为同一类别 包含可识别的子系统标记。时间线总是路由到 host/timing.logagent/timing.log;未知子输出到那个 频道的 runtime.log。每条记录都包含其 category 字段。

不再写入平面 app.loghost.logagent.log 名称。 现有的旧文件在布局转换期间保持不变。

4. 必填字段

每个结构化日志行应包括:

ts
type LogRecord = {
  ts: string
  level: "debug" | "info" | "warn" | "error"
  channel: string
  category: string
  message: string
  traceId?: string
  sessionId?: string
  turnId?: string
  toolCallId?: string
  pluginId?: string
  code?: string
  data?: unknown
}

格式化 MVP:NDJSON 文件。

5. 必须记录的内容

总是

  • 应用程序 boot/shutdown
  • host/agent 生成 + 握手结果
  • 会话 create/delete
  • 提示 accepted/aborted
  • 工具 start/end
  • 许可 request/decision/timeout
  • Plan 工件创建(唯一路径、SHA-256、字节大小)、approval/expiry/ 拒绝、执行转换和启动中断
  • shell ID/effective 方言、availability/fallback 或更改选择失败、流 字节计数、超时和进程树关闭
  • 插件 enable/disable/load/error
  • 工具准入拒绝、队列深度、活动类预算和 shell 生成 资源耗尽

从来没有

  • API 密钥/原始秘密
  • 完全安全的存储有效负载
  • 审计中大量读取不必要的完整文件内容(使用 hashes/previews)

6. 编辑规则

  1. /token|secret|password|api[_-]?key/i 匹配的密钥经过编辑
  2. 编辑授权标头
  3. 工具参数预览被截断(例如 2KB) 4、审计时长命令输出为counted/truncated; stdout/stderr 块是 从未在正规渠道批发过

7. 迹线相关性

尽可能为每个用户可见的操作使用一个 traceId

  • 提示→turnId
  • 工具调用 → toolCallId
  • 权限流共享 toolCallId/requestId

Renderer、Electron、主机、代理应传播这些 ID。

7a。延迟分段 (D183)

缓慢的代理转动在该工具内几乎从不慢。等待属于 三个阶段之一,每个阶段都单独记录,以便可以告诉他们 不加猜测地分开:

舞台哪里领域
批准host-core tools.executepermission_wait_ms
工具体host-core 工具实现execute_ms(审核中的 durationMs
主机簿记host-core(工作区解析、锁定、工件、审核)overhead_ms
飞行前指令sidecar,tools.execute 之前的路径范围链instructionResolveMs
房东往返费用包括IPCsidecar 周围 tools.executehostRttMs
提供商优先令牌sidecar,请求 → message_startproviderWaitMs
提供商流媒体sidecar、message_startmessage_endstreamMs
  • host-core 在 host 通道上的每次调用发出一条 tool timingpromptedpermission_wait_msexecute_msoverhead_mstotal_ms、 和 outcomeok / error / denied);相同的字段被持久化 tool_execute / tool_denied 审核行。
  • sidecar 写入 grepable [timing] kind=<tool|model|subagent> key=value 到 stderr 的行,Electron Logger 将其包装到 agent 通道中。 设置 PI_DESKTOP_TIMING=0(或 toolCallId/requestId/Electron)来抑制它们。
  • hostRttMs 减去同一 toolCallId 的主机的 total_ms 是 stdio/IPC 成本; providerWaitMs 覆盖 pi-ai 自己的重试退避,因此 烧毁重试的提供程序会出现在那里,而不是作为一个缓慢的工具。
  • instructionResolveMs 测量路径范围指令预检和 不属于指挥机构。 instructionCacheHit=true 识别 相同提示目录声明; instructionFallback=base 识别 运行时的基链继续超时或解析器故障。
  • 失败或中止的回合仍会发出 kind=model 行和结果,因此 从未产生代币的回合仍然是可衡量的。
  • 一条 kind=subagent 行关闭每个 Task 调用(D201、ADR 0062) agenttoolCallIdsessionIdturnIdprovidermodelstatus、 失败时为 turnstoolCallsdurationMserrorCode。代表行 在转录中归因,但他们的工具和模型线没有,所以 这就是并行扇出的区别:相同的 turnId,每行一行 委托,每个委托都有自己的提供商和挂钟成本。

助理成绩单还保留成功的流持续时间为 UiMessage.responseDurationMs。渲染器将其与提供商报告的相结合 输出令牌以显示 tokens/s 中的生成速度;这是一个演示 相同 streamMs 间隔的投影,而不是第二个定时源。工具 行带有单独的上下文估计 argument/result 足迹 检查,而提供商 input/output 的准确使用仍然具有权威性。

Plan 和 shell 记录使用相同的 sessionIdturnIdtoolCallId 相关字段。工件日志仅包含下的唯一相对路径 .pi/plan/、哈希值和大小; shell 日志包括目录 ID 和方言, 绝不是来自渲染器的任意可执行命令行或路径哈希。

8. 面向用户的诊断

MVP 提供:

  1. 应用内错误文本及代码 2.“打开日志文件夹”命令 3.可选复制错误详细信息(代码+traceId)

不在 MVP 中:

  • 远程遥测管道
  • 云崩溃分析(可以在同意后添加)

9. 保留

  • app/host/agent 类别日志:大小上限轮换 — 轮换每个类别 文件大小为 5 MB,在其旁边保留 2 个旋转文件(<category>.1.log<category>.2.log
  • 审核日志(SQLite):与数据库一起保留;比调试日志长
  • 轮换决不能让调用者失败;磁盘故障被吞噬

10. 验收

  1. 失败的工具调用可以通过toolCallId跨日志追踪
  2. 在正常流程中,秘密永远不会出现在日志文件中
  3. 可从 app/command 调色板打开日志文件夹
  4. 工具调用缓慢可归因于批准、执行或提供商 仅从日志中(D183)
  5. 主机资源事件暴露了 active/queued 工具预算和单个 重新启动生成而不是重复的陈旧管道错误
  6. Plan 启动中断和 shell changed-selection/timeout/process 中止 可以从session/turn/tool-call相关性和稳定误差进行诊断 代码

为本地优先开发而构建。