opencodex GUI 日志表格打磨实战:Token 本地化格式、Request ID 钳制与状态码详情弹窗

发布时间:2026/9/23 19:23:36
opencodex GUI 日志表格打磨实战:Token 本地化格式、Request ID 钳制与状态码详情弹窗 【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载opencodex 是面向 OpenAI Codex CLI / App / SDK 与 Claude Code 的通用提供商代理universal provider proxy其内置 Web GUI 提供了请求日志Logs页面用于逐条追踪每次 LLM 调用。本文以仓库开发日志 devlog/_fin/260706_logs-table-polish/000_plan.md 记录的一次 Logs table polish 迭代为主线完整讲解该次优化的五项需求、四个落地阶段并结合 format-tokens.ts、status-codes.ts、Logs.tsx 等源码剖析移动端优先的表格渲染、locale 感知的 token 缩写、以及状态码 详情弹窗的排障交互是如何实现的。读完本文你将掌握 opencodex 日志表格的列宽体系、i18n 键组织方式与错误诊断弹窗的完整数据流可直接用于复现、评估或二次开发这套日志界面。一次移动端优先的日志表格打磨需求全景该迭代由 GUI 的 #logs 页面收到的移动端mobile-first反馈驱动共列出五项具体抱怨与对应改造点全部围绕信息密度与可读性#用户反馈目标行为1缓存 token 显示为c 6.9만cache 标签缩短为单个c数值保留一位小数2主 token 数字同样采用一位小数舍入规则3Request id 撑爆表格省略号ellipsis钳制最多 2 行杜绝表格被撑爆4Error 列过宽收窄 Error 列把空间还给其他列5错误信息不直观状态码如502 details 入口点击弹出 modal展示该请求详细日志 按状态码的解释如 429 rate limit并支持 en/ko/zh 本地化这五项需求被拆分为四个落地阶段P1–P4每阶段都有明确的验收标准Criteria最终由提交616a443合并关闭详见 devlog/_fin/260706_logs-table-polish/999_closed.md全量测试套件 1555 通过 / 0 失败。P1Locale 感知的 Token 缩写与一位小数舍入阶段 P1 的目标是重写 token 格式化逻辑验收标准为韩语环境下显示6.9만英语环境显示176.6K这类风格缓存部分渲染为c 6.9만。核心实现位于 format-tokens.ts该模块被 Dashboard / Usage / Logs 三个页面共享。双套单位体系西方千进制与 CJK 万进制源码注释明确说明了设计意图西方 locale 使用 K/M/B/T 千进制CJK localeko/zh/zh-TW使用万进制myriad1e4 进制韩语为만/억/조/경简体中文为万/亿/兆/京繁体中文为萬/億/兆/京这样读起来更自然const CJK_UNITS: Recordstring, Array{ v: number; s: string } { ko: [{ v: 1e16, s: 경 }, { v: 1e12, s: 조 }, { v: 1e8, s: 억 }, { v: 1e4, s: 만 }], zh: [{ v: 1e16, s: 京 }, { v: 1e12, s: 兆 }, { v: 1e8, s: 亿 }, { v: 1e4, s: 万 }], zh-TW: [{ v: 1e16, s: 京 }, { v: 1e12, s: 兆 }, { v: 1e8, s: 億 }, { v: 1e4, s: 萬 }], };一位小数规则与尾部零裁剪本次打磨的关键变化是统一采用toFixed(1)保留一位小数同时通过trim函数把12.00만这样的尾部零裁掉呈现为12만function trim(s: string): string { return s.replace(/\.0$/, ).replace(/(\.\d*?)0$/, $1); } export function formatTokens(n: number, locale: string): string { const units CJK_UNITS[locale]; if (units) { for (const u of units) { if (n u.v) { return ${trim((n / u.v).toFixed(1))}${u.s}; } } return String(n); } if (n 10_000) return String(n); if (n 1_000_000) return ${trim((n / 1000).toFixed(1))}K; if (n 1_000_000_000) return ${trim((n / 1_000_000).toFixed(1))}M; if (n 1_000_000_000_000) return ${trim((n / 1_000_000_000).toFixed(1))}B; return ${trim((n / 1_000_000_000_000).toFixed(1))}T; }从实现可推断出完整的行为矩阵小于 1 万的数字原样输出西方 locale 按 1000 / 1e6 / 1e9 / 1e12 四档分别映射 K / M / B / TCJK locale 则从大到小匹配만/억/조/경等单位。一位小数适用于所有被缩放的数值这正是 P1 验收标准中主 token 数字也走一位小数舍入的落点。缓存 token 的c前缀渲染在日志表格的 token 单元格中Logs.tsx主 token 与缓存拆分并存cacheSplit(log)返回{ read, write }两个值分别渲染为带ccache read与wcache write前缀的第二行小字{tokenTotal ! undefined ? ( span classNamelogs-stack-end span{log.usageStatus estimated ? ~ : }{formatTokens(tokenTotal, locale)}/span {(read ! undefined read 0) ( span classNamemuted text-caption leading-tightc {formatTokens(read, locale)}/span )} {(write ! undefined write 0) ( span classNamemuted text-caption leading-tightw {formatTokens(write, locale)}/span )} /span ) : ( span classNamemuted{t(logs.tokens.${log.usageStatus ?? unreported})}/span )}配合displayContextTokenTotal对 Kiro 这类有状态提供商用contextTotalTokens绝对上下文快照取最大值单元格内形成主 token c/w 缓存拆分的纵向堆叠布局6.9만与c 6.9만的视觉层级由此而来。注意源码注释特别警告contextTotalTokens是快照而非增量绝不能跨请求求和聚合汇总必须继续使用displayTokenTotal。P2Request ID 两行钳制与列宽再平衡阶段 P2 解决表格布局问题验收标准为 399px 宽截图下 request id 最多显示两行、error 列明显收窄。实现分布在 styles.css。Request ID 的省略号钳制requestId单元格使用-webkit-line-clamp两行钳制 全词断行防止长 ID 撑爆表格.log-reqid { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-all; max-width: 14ch; }单元格本身保留完整值用于 tooltipspan classNamelog-reqid title{log.requestId}截断不影响复制与检索。固定布局下的列宽体系表格采用table-layout: fixedcolgroup中 10 个列各占固定百分比Logs.tsx 与 styles.css 同步定义列CSS 宽度time12%tokens9%rate7%cost8%model15%effort9%provider13%status8%request11%duration8%表格整体min-width: 1100px保证移动端下仍然可控地横向滚动而非挤爆。状态列从原先较宽的 Error 列收窄为 8%正是把空间还给其他列的直接体现。单元格级溢出裁剪值得注意的细节table-layout: fixed只会定宽不会裁剪内容——过宽内容会直接画出单元格、盖住邻居列源码注释记录了US$0.1401claude-fable-5-1与reasoning_efforthigh盖住 provider 列的实测现象。因此配套规则是.logs-table tbody td { overflow: hidden; }把超长值截断在自身列内而 details 按钮因可能遇到如繁体中文檢視詳細資料这类较长的本地化文案特意用white-space: normal允许换行而非裁剪。P3状态码字典与行详情弹窗阶段 P3 是本轮打磨的功能核心新增状态码解释字典 status-codes.ts由子代理 gpt-5.5 构建并在点击行内 details 按钮时打开包含代码解释 原始日志 JSON的详情弹窗。验收标准点击行 / details 按钮打开 modal429 / 502 显示本地化 label 与 description。状态码字典的数据结构status-codes.ts定义了StatusCodeInfo { label; description }结构覆盖 400 / 401 / 402 / 403 / 404 / 408 / 409 / 413 / 422 / 424 / 429 / 499 / 500 / 502 / 503 / 504 / 529 共 17 个状态码每个状态码提供10 种语言en / de / fr / ko / zh / zh-TW / ru / ja / tr / vi的本地化解释。以 429 为例429: { en: { label: Rate limited, description: The upstream provider rate or quota limit has been reached. Wait for the quota window to reset or switch account/provider. }, ko: { label: 한도 초과, description: 업스트림 제공자의 속도 또는 할당량 한도에 도달했습니다. 한도 창이 초기화될 때까지 기다리거나 계정/제공자를 전환해야 합니다. }, zh: { label: 限流, description: 已达到上游提供商的速率或额度限制。请等待额度窗口重置或切换账号/提供商。 }, ... }除精确匹配外字典还提供了通用回退4xx 未收录码落到GENERIC_STATUS.clientRequest error5xx 落到GENERIC_STATUS.serverServer or upstream error保证任何状态码都能给出有意义的解释。normalizeLocale负责把浏览器 locale 前缀如fr-FR归一化到字典键未匹配语言统一回退英文。查询入口statusCodeInfo(code, locale)export function statusCodeInfo(code: number, locale: string): StatusCodeInfo | null { if (code 400) return null; const normalizedLocale normalizeLocale(locale); const info STATUS_CODES[Math.trunc(code)] ?? (code 500 ? GENERIC_STATUS.client : GENERIC_STATUS.server); return info[normalizedLocale]; }在 Logs.tsx 中选中某行后立即求值const detailInfo detail ? statusCodeInfo(detail.status, locale) : null;并随详情对象一并传入弹窗。状态单元格与详情弹窗交互表格的 status 单元格Logs.tsx纵向堆叠状态码 details 按钮td span classNamelog-status-cell span classNamemono font-semibold style{{ color: statusColor(log.status) }}{log.status}/span button typebutton classNamelog-detail-btn onClick{() setDetail(log)} aria-label{${t(logs.details)}: ${log.requestId ?? log.status}} {t(logs.details)} /button /span /tdstatusColor定义了状态语义色2xx 绿色、4xx 红色、其余琥珀色。点击按钮设置detail状态触发LogDetailDialog渲染。LogDetailDialogLogs.tsx基于原生dialogshowModal()实现无第三方弹窗依赖标题区彩色状态码 本地化 label如502 Bad upstream response下方是本地化 description 段落基本信息区时间、request id含一键复制按钮、conversation id可一键反查过滤、模型、提供商、effort、errorCode、upstreamError路由决策区展示routeDecision的 routeKind、profile、选中目标provider/model reason与候选列表✓/✗/? 标记 eligible性能区duration、端到端 tok/s、decode tok/s、TTFT不可用原因以本地化 key 展示成本区total/input/cacheRead/cacheWrite/output 各项费用估算、命中的价格来源jawcode/expected/user与验证状态以及估算原因列表尝试列表区当请求包含多次重试attempts时逐条展示每次尝试的目标、耗时、tok/s、估算费用与失败原因recoveryKinds会映射为本地化标签如rate-limit-429→ 限流文案Usage 区input/output/cacheRead/cacheWrite/reasoning 与 total 的完整 token 拆分原始 JSONdetails折叠区内JSON.stringify(detail, null, 2)输出完整日志对象满足详情弹窗包含原始日志 JSON的验收标准。日志数据管道2 秒轮询与游标分页弹窗所展示的数据来自 Logs.tsx 的loadLogs以GET {apiBase}/api/logs?limit2000cursor...每 2 秒轮询LOGS_POLL_INTERVAL_MS 2000携带游标增量拉取失败时按2 ** min(failures, 4)指数退避连续 3 次失败或关闭自动刷新后的一次失败才在表格上方提示数据可能过期避免瞬时 5xx 在可读表格上闪烁噪音。行渲染使用 TanStack Virtual 虚拟化estimateSize: 92overscan 15保证移动端数千行的滚动性能服务端时区通过/api/settings的timeZone字段获取避免时间戳被浏览器本地时区静默偏移。P4i18n 键与验证闭环阶段 P4 负责补齐 i18n 键、重建并验收。仓库的 i18n 语言文件位于 gui/src/i18n/en / ko / zh 等以logs.col.*命名空间组织表头文案例如logs.col.requestRequest / 요청 / 请求logs.col.statusStatus / 상태 / 状态logs.col.errorError / 오류 / 错误logs.col.time、logs.col.tokens、logs.col.tokPerSec、logs.col.estimatedCost、logs.col.model、logs.col.effort、logs.col.provider、logs.col.duration等构成完整表头详情弹窗则使用logs.detail.*命名空间section.basic / section.route / section.performance / section.cost / section.attempts / section.usage / copyRequestId / copied / attempt.recovery.* 等logs.tokens.*承载 token 相关文案input / output / cacheRead / cacheWrite / reasoning / contextTotal / estimatedNote 等。status-codes.ts自带 10 语言字典因此弹窗的代码解释不依赖 i18n 文件即可完成本地化。该阶段的验收动作包括重建前端、使用 Playwright 分别截取移动端与桌面端截图核对布局、运行tsc类型检查。最终提交616a443合入测试全绿1555 pass / 0 fail迭代闭环记录在 999_closed.md。从这次打磨中可沉淀的设计要点本地化不只是翻译还包括数字体系CJK 用户读만/万比K更自然formatTokens用一套函数同时承载单位选择、小数位与尾部零裁剪被 Dashboard / Usage / Logs 三处共享避免了各页面格式化规则漂移。表格布局要同时处理定宽与裁剪两个问题table-layout: fixed解决列宽分配单元格级overflow: hidden解决超长内容越界覆盖邻居列line-clamp解决 request id 这类长标识符的展示。排障信息要一眼可见、一键深入状态码列只放精简信息数字 颜色 details 入口完整上下文路由决策、重试尝试、成本、原始 JSON全部收进按需打开的弹窗既保住表格密度又让排障者可拿到全部证据。错误码解释要做兜底状态码字典对未知 4xx/5xx 提供通用 client/server 文案保证任何错误码都能给出可操作的下一步建议重试、切换提供商、检查凭据等这是日志型界面的实用性底线。如需进一步深入可继续阅读 Logs.tsx 的完整实现筛选栏logs-filter.ts、会话聚合、成本估算logs-cost-format.ts以及 structure/decisions 下的相关设计决策记录。赞分享【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载相关推荐opencodex GUI 打磨实战Dashboard/Usage 页面的排版平衡、响应式热力图与 Token 计量重构opencodex GUI 打磨实战Dashboard/Usage 页面的排版平衡、响应式热力图与 Token 计量重构 Dashboard 与 Usagex64dbg 断点日志命令 SetBreakpointLogbpl/bplog详解日志文本、格式化表达式与条件日志x64dbg 断点日志命令 SetBreakpointLogbpl/bplog详解日志文本、格式化表达式与条件日志 本篇技术指南聚焦 x64dbg 的命令逆向工程调试器开发工具应用安全Polars Config 使用指南表格格式化、状态持久化与作用域控制详解Polars Config 使用指南表格格式化、状态持久化与作用域控制详解 Polars 的 Config 模块是调节运行时行为的统一入口覆盖终端中 Dat数据分析大数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询