CodeBurn 中 OpenCode 用量追踪:数据目录解析、双代存储格式与计费路由实战指南 【免费下载链接】codeburnFree, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn项目地址https://gitcode.com/gh_mirrors/co/codeburn点击查看免费下载CodeBurn 是一款本地运行的 AI 编程用量与成本追踪工具支持包括 OpenCodesst/opencode在内的数十种工具与 Agent。本文以 docs/providers/opencode.md 为核心结合 src/providers/opencode.ts 等源码与 tests/providers/opencode.test.ts 测试系统讲解 CodeBurn 如何发现并解析 OpenCode 会话数据数据目录的解析优先级与 fork 适配环境变量、从文件 JSON 到 SQLite 再到 2.x 双代次的存储格式演进、按sessionId:messageId的去重策略以及providerID驱动的计费路由与各类已知怪癖。读完本文你将掌握为 OpenCode或其兼容 fork如 MiMoCode正确配置 CodeBurn、排查解析告警并验证用量统计的完整方法。一、Provider 定位懒加载的 OpenCode 适配器OpenCode 是 CodeBurn 中的懒加载Provider 之一它不在进程启动时强制引入而是由注册表按需加载。从 src/providers/index.ts 可以看到opencode被列入lazyProviderNames与lazyProviderDisplayNames显示名为OpenCodeloadOpenCode()通过动态import()在首次需要时加载 src/providers/opencode.ts加载失败也不会拖垮整个发现流程。所有 Provider 的发现结果通过discoverAllSessionsWithFailures并发收集并做失败隔离——某个 Provider 的目录扫描异常只会打印一条codeburn: skipped ... discovery after an error警告而不会清空其他 Provider 的用量数据。Provider 对象本身在 src/providers/opencode.ts 中定义probeRoots()返回数据目录作为探测根discoverSessions()同时调用文件式与 SQLite 两套发现器并合并结果createSessionParser()则按source.path是否以.json结尾把解析委托给文件解析器或 SQLite 解析器。此外它还负责模型与工具的显示名映射模型名会去掉model/形式的 provider 前缀后交给共享的getShortModelNamesrc/providers/opencode.ts内置工具如bash/edit/task会被映射为Bash/Edit/Agent等可读名称。二、数据从哪里读目录解析优先级与环境变量2.1 默认数据目录OpenCode 的会话数据默认位于~/.local/share/opencode/若设置了XDG_DATA_HOME则位于$XDG_DATA_HOME/opencode/。目录发现器会拾取该目录下的所有opencode*.db文件SQLite 形态以及storage/子目录文件 JSON 形态。目录解析逻辑集中在getDataDir()src/providers/opencode.ts。当没有传入dataDir参数即生产路径时优先级为OPENCODE_DATA_DIR → $XDG_DATA_HOME/opencode → ~/.local/share/opencodeOPENCODE_DATA_DIR是精确的数据目录——不会追加opencode后缀。这一点与测试桩路径不同测试中传入的dataDir参数仍会被拼上opencode子目录join(dataDir, opencode)以保持既有测试固件不变如tmpDir/opencode/opencode*.db。2.2 为 OpenCode 兼容 fork 重定向数据OPENCODE_DATA_DIR / OPENCODE_DB_PREFIXOpenCode 生态中存在改名或 fork 的兼容构建例如 MiMoCode 会把数据写到~/.local/share/mimocode/mimicode.db但使用与 OpenCode 完全相同的session/message/part表结构。要让 CodeBurn 找到这类 fork 的数据需要同时设置两个环境变量对应 issue #617 的修复环境变量含义默认值示例OPENCODE_DATA_DIR精确的数据目录不追加opencode后缀同时重定向文件存储与 SQLite 存储无回落$XDG_DATA_HOME/opencode/~/.local/share/opencodeOPENCODE_DATA_DIR$HOME/.local/share/mimocodeOPENCODE_DB_PREFIXSQLite 文件名前缀匹配前缀*.db仅影响 SQLite 发现opencodeOPENCODE_DB_PREFIXmimicode可发现mimicode*.db值得注意的细节是OPENCODE_DB_PREFIX的读取用的是真值判断而非空值合并src/providers/opencode.ts空字符串前缀会回退为opencode。若用??空字符串会存活下来导致discoverSqliteSessions用filename.startsWith()匹配所有*.db文件把无关数据库扫进发现流程。这与OPENCODE_DATA_DIR的真值处理保持一致也让未设置与设置为空行为相同——这与环境指纹一致因为computeEnvFingerprint会把两者都折叠为OPENCODE_DB_PREFIX。文件存储则不受OPENCODE_DB_PREFIX影响只要OPENCODE_DATA_DIR指向了 fork 的数据目录数据目录/storage/下的 JSON 文件就会被发现src/providers/opencode.ts 中文件与 SQLite 两套发现并行执行。2.3 环境变量与缓存指纹这两个变量连同XDG_DATA_HOME一起参与了 OpenCode 的会话缓存环境指纹src/session-cache.ts。也就是说修改OPENCODE_DATA_DIR或OPENCODE_DB_PREFIX会改变缓存指纹使热读与冷读结果保持一致不会出现旧指纹下缓存命中导致数据不更新的问题。配置清单亦收录在 docs/configuration.md。三、存储格式演进文件 JSON、legacy SQLite 与 2.x 双代次OpenCode 的历史版本使用三种互有重叠的存储形态CodeBurn 全部兼容3.1 文件式 JSONOpenCode 1.1OpenCode 1.1 之后将会话存为文件 JSON目录结构如下见 src/providers/opencode-file-parser.ts 的注释storage/session/projectID/sessionID.json 会话元数据 storage/message/sessionID/messageID.json 每条消息一个文件 storage/part/messageID/partID.json 每个 part 一个文件消息/part 的结构与 SQLite 布局一致因此每消息的构建逻辑通过共享的buildAssistantCallsrc/providers/session-message.ts复用。解析器按time.created排序消息用户消息的文本会被记住并作为后续助手调用的userMessage归因只对assistant/model角色产出调用。3.2 legacy SQLitesession / message / part旧版 OpenCode 将数据写入opencode*.db含session、message、part三张表。CodeBurn 以只读方式查询并按 LiteLLM 价格重新计算成本对无价目模型则回退使用 OpenCode 自己写入的cost字段docs/how-it-works.md。message.data与part.data均为 JSON 载荷providerID就存放在 assistant 消息的载荷中。3.3 OpenCode 2.xsession_v2 session_messageissue #1293OpenCode 2.x主线自 2.0.3 起issue #1293写入第二套 SQLite 代次session_v2session_message。session_message的外键指向session_v2(id)消息由type列打标签、按seq排序、载荷 JSON 放在data列。原地升级后legacy 的session/message/part表会冻结——升级后的会话在session_message中有行而message表不再新增行。解析器在 src/providers/sqlite-session-parser.ts 按数据库粒度通过sqlite_master探测当session_v2与session_message存在时以 v2 为准legacy 表被整体忽略两代次永不 JOIN否则走 legacy 路径。同时存在一个兼容细节legacy 中那些 id 未进入session_v2的会话并未作废——它们仍以 legacy 读取器解析src/providers/sqlite-session-parser.ts避免升级后旧会话用量凭空消失。会话级的成本/token 汇总与parent_id子会话遍历在两个代次中都存在因此发现、解析与去重在两种 schema 下行为一致。对应的 v2 测试固件见 tests/providers/opencode.test.ts。四、缓存与去重缓存OpenCode provider无独立缓存。每次发现都是直接扫描数据目录冷启动即拿到最新数据。去重按sessionId:messageId粒度进行。去重键在文件解析器里形如opencode:sessionId:messageIdsrc/providers/opencode-file-parser.ts与 SQLite 路径共用同一seenKeys集合——这使文件 SQLite 双形态并存的迁移期升级后 legacy JSON 仍在磁盘、新数据流入 SQLite不会重复计数旧会话与新会话都能上报。两种形态的每消息构建均经buildAssistantCall共享保证 token、工具、成本归因一致src/providers/session-message.ts。五、计费路由providerID 如何映射到账单OpenCode 把传输通道transport记录在每条 assistant 消息的providerID字段里。CodeBurn 在 legacy SQLite、v2session_message、文件存储以及会话级汇总回退之间一致地保留这些承载用量语义的值然后通过 src/models.ts 的routeFromProviderField映射为计费路由providerID值路由计费方式openrouterOpenRouter按量计费meteredamazon-bedrockBedrock按量计费metered映射定义于 src/models.ts 的路由表bedrock的providerFields包含bedrock与amazon-bedrockopenrouter的providerFields为openrouter。关键约束大小写或空白变体不做推断若原始值是OpenRouter或带首尾空格routeFromProviderField会因value ! normalized而返回undefined落入 unrouted/unknown。Bedrock 模型检测器仍是兜底对于能被识别的 Anthropic / OpenAI 基础模型 id旧有的 model-id 检测器依然生效但providerIDamazon-bedrock还覆盖了 Nova 等 id 与检测器不匹配的模型家族。直连 provider 值如openai、anthropic保持 unrouted/unknown不强行猜测。测试对两条路由均有断言openrouter与amazon-bedrock消息分别产出route: openrouter与route: bedrocktests/providers/opencode.test.ts。共享字段指纹由于 OpenCode 与 KiloCode 共用这套 provider 字段映射映射一旦变化两者的会话缓存指纹会同步移动保证热读与冷读一致src/session-cache.ts 中两 provider 共享相关环境指纹键。六、解析怪癖与语义细节6.1 只发根会话遍历整棵 parent_id 子树OpenCode 的子 Agentsubtask会话通过parent_id关联。为避免重复计数发现阶段只输出根会话parent_id IS NULL见 src/providers/sqlite-session-parser.ts解析根会话时再沿session.parent_id走完整棵子树——归档的子会话也包含在内。OpenCode 的归档是组织性的行不会删除因此子会话与孙会话的 message、token、工具用量都会归并回根会话。两个相关测试归档会话可被发现#1362归档子会话计入根子树#1362断言子会话的去重键为opencode:archived-child:msg-child-assistanttests/providers/opencode.test.ts、tests/providers/opencode.test.ts。6.2 parts 索引顺序决定推理 token 正确性每条消息的parts会被建立索引保持顺序对推理 tokenreasoning tokens的正确性至关重要。若出现reasoning tokens 差一off by one类 bug优先排查 parts 索引排序逻辑。6.3 token 维度与成本语义token 按input、output、reasoning、cache.read、cache.write五个维度上报Anthropic 语义。推理 token 按输出价计费——会话级与每消息级回退都必须按 output reasoning 计价而非只算 output#1334见 tests/providers/opencode.test.ts。6.4 零成本消息的取舍缺 router usage 的 assistant 消息只要 parts 包含非空文本或工具活动就保留为零成本调用空的、零用量的 assistant 占位符仍然跳过v2 代次中compaction类型消息携带 CompactionUsage成本/token 在 compaction 行上完成态 compaction 计入统计运行中的 compaction无用量不产出任何调用tests/providers/opencode.test.ts。6.5 MCP 工具名归一化OpenCode 将外部 MCP 工具存为server_tool形式例如clickup_clickup_get_task。normalizeToolNamesrc/providers/session-message.ts会将其归一化为 CodeBurn 的规范命名mcp__server__tool使共享的 MCP 面板与optimize发现能够统计 OpenCode 的 MCP 用量对已经是mcp__前缀的名字原样保留。测试断言clickup_clickup_get_task与figma_get_file分别归一化为mcp__clickup__clickup_get_task、mcp__figma__get_filetests/providers/opencode.test.ts。解析时还会从 bash 工具的state.input.command提取 bash 命令串供命令类报表使用。6.6 Schema 校验吵一点是正确行为当必需表缺失时解析器会打印一条可操作的警告指明哪张表缺失以及期望的 OpenCode 版本。不要静默吞掉这类警告——它通常是升级后 schema 变化的第一信号。6.7 源码路径编码与项目识别会话源码路径编码为dbPath:sessionId如/home/user/.local/share/opencode/opencode.db:ses_v2_1测试固件也遵循该格式。项目名取自会话的directory或title经sanitize处理如/home/user/myproject→home-user-myproject。七、调试与测试指引tests/providers/opencode.test.ts是当前仓库中最大的 provider 测试文件已超过 1400 行覆盖文件 JSON、legacy SQLite、v2 双代次、路由、MCP 归一化、归档子树、推理 token 计价等场景另有 tests/providers/opencode-file.test.ts 专测文件存储形态。改动 OpenCode provider 前后的标准做法先跑全套测试npx vitest run tests/providers/opencode.test.ts回归后再做改动。若遇到 missing table 警告不要 catch 后静默。要么升级解析器中的版本预期要么在文档中记录该破坏性 schema 变更。若遇到 reasoning tokens off by one检查 parts 索引排序。若某个 OpenCode 兼容 fork如 MiMoCode扫出零会话检查OPENCODE_DATA_DIR是否精确指向 fork 的数据目录、OPENCODE_DB_PREFIX是否与*.db文件名前缀一致注意该变量仅影响 SQLite 发现文件存储不受其约束。八、小结CodeBurn 对 OpenCode 的支持建立在三条支柱上精确的目录解析OPENCODE_DATA_DIR/OPENCODE_DB_PREFIX使其可适配任意兼容 fork、三代存储形态的无缝兼容文件 JSON、legacy SQLite、2.xsession_v2双代次并存不重不漏、以及以providerID为准的计费路由OpenRouter/Bedrock 按量计费直连值保持未知。理解这些机制后无论你的 OpenCode 处于哪个版本或使用了何种改名构建都能让 CodeBurn 给出与官方文档一致的 token 与成本统计。若要深入实现细节可继续阅读 src/providers/opencode.ts、src/providers/sqlite-session-parser.ts、src/providers/session-message.ts 及对应测试。赞分享【免费下载链接】codeburnFree, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn项目地址https://gitcode.com/gh_mirrors/co/codeburn点击查看免费下载相关推荐codeburn 中的 Gemini CLI 用量解析器数据来源、存储格式、计费去重与调试指南codeburn 中的 Gemini CLI 用量解析器数据来源、存储格式、计费去重与调试指南 GeminiGoogle Gemini CLI是 codeCodeBurn 的 Kimi Code 会话解析指南wire.jsonl 存储格式、Token 计量与去重原理CodeBurn 的 Kimi Code 会话解析指南wire.jsonl 存储格式、Token 计量与去重原理 本指南以 CodeBurn 仓库 httpsOpenEBS存储数据流分析追踪数据路径OpenEBS存储数据流分析追踪数据路径 引言 你还在为Kubernetes集群中的数据存储路径不透明而困扰吗当应用数据在OpenEBS中流转时你是否清楚云原生CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考