遥测、更新与诊断
三个默认关闭、逐项同意的遥测通道,本地的事故记录与观测日志,签名清单与多种安装来源下的自更新,每日签到,以及排查问题用的诊断命令。
模型请求之外,mcode 进程还有几类“产品自己的流量”:使用统计、运行时指标、错误诊断、更新检查、签到和用户反馈。源码导入当天的提交 36bd09392a0b(2026-09-18,“fix: require separate consent for automatic telemetry uploads”)把其中所有自动上传都改成了默认关闭、逐项同意。本篇先讲这几个通道现在的行为,再讲自更新、签到与诊断入口。
怎么用
三个开关都在 config.yaml 的 telemetry 段。docs/telemetry.md:10 给的示例只打开了使用事件:
telemetry:
enabled: true # TUI usage events (anonymous, described below)
metrics: false # Runtime counters, gauges, and histograms
diagnostics: false # Account-linked TUI and LLM error diagnostics- 配置文件在数据目录(默认
~/.minimax-code,packages/tui/src/runtime/data-dir.ts:21)的config.yaml里。三个键缺省都是false(packages/config/src/config.ts:1772),metrics与diagnostics只有写成布尔值true才算同意(config.ts:2105)。 - 环境变量
MCODE_DISABLE_TELEMETRY或DO_NOT_TRACK取1、true、yes、on(不分大小写)时三个通道全关,优先于配置文件(packages/config/src/telemetry-policy.ts:5)。 mcode telemetry status打印每个通道的生效状态、被哪个环境变量挡住、配置文件路径;mcode telemetry preview打印一条解码后的示例请求(固定是tui_launch),不会发送,使用事件没开时request为null(packages/tui/src/cli/telemetry-command.ts:26)。- 更新:TUI 每次启动都在后台检查,有新版就在欢迎页提示;
/update在 TUI 里升级(要输入搜索才出现在菜单里),mcode update在命令行升级,交互终端里会先问一句[y/N](packages/tui/src/cli/update.ts:70)。代码里没有找到关闭启动检查的开关。 - 签到用
/checkin;诊断命令见文末。
三个通道
| 通道 | 配置键 | 内容 | 发往 | 身份 |
|---|---|---|---|---|
| 使用事件 | telemetry.enabled | 启动、登录、发消息、打开斜杠与 @ 菜单等 10 种事件 | 按地区与构建环境选的 meerkat-reporter 地址 | 每条事件一个新的随机 ID,不带账号 |
| 运行时指标 | telemetry.metrics | 计数、仪表、直方图与少量低基数标签 | Matrix 的指标批量接口 | 文档称不附账号凭据 |
| 错误诊断 | telemetry.diagnostics | TUI 事故与 LLM 请求失败的最小化摘要 | /minimax-cloud/api/v1/observability/desktop-errors/batch | Bearer token 加 user_id 参数,绑定账号 |
后两个通道共用一个开关函数(telemetry-policy.ts:11):
export function isTelemetryChannelEnabled(
channel: TelemetryChannel,
readConfigured: () => boolean | undefined = () => getConfig().telemetry[channel],
): boolean {
for (const key of TELEMETRY_OPT_OUT_ENV) {
if (/^(?:1|true|yes|on)$/iu.test(process.env[key]?.trim() ?? '')) return false;
}
try {
return readConfigured() === true;
} catch {
return false;
}
}两条规则:环境变量先于一切;配置读不出来按“未同意”处理。使用事件走另一个函数 resolveMcodeBusinessTelemetryPolicy(),环境变量的判定一样(packages/tui/src/analytics/business-telemetry.ts:126),但只在启动时读一次配置,不开就根本不创建客户端(packages/tui/src/tui/launcher.ts:237),所以改完要重启。诊断通道则每次记录、每次上传前都现查一次;/reload 会清掉配置缓存,从代码推断,改了 diagnostics 之后执行一次 /reload 就能生效。
这个提交改了什么
按 36bd09392a0b 的 diff 对比:
| 通道 | 之前 | 现在 |
|---|---|---|
| 运行时指标 | 托管运行时一律创建云端上报器;生产与预发构建都算托管(config.ts:166) | 还要 telemetry.metrics 为真(packages/local-runtime/src/runtime/host-metrics.ts:112) |
| LLM 请求失败报告 | 登录即上传 | 进缓冲前、加密发送前各查一次(packages/local-runtime/src/error-reporting/reporter.ts:107、reporter.ts:65) |
| TUI 事故 | 写成待上传文件,登录后自动上报 | 未同意时写成只留本地的文件;排空和每批发送前再查一次(packages/tui/src/observability/incident-reporter.ts:320) |
| 使用事件 | 已经默认关闭 | 不变 |
指标与 LLM 报告的装配在第一代宿主的 host-factory.ts 里,运行时 v2 启动时会在内部建一个 v1 宿主(packages/local-runtime-v2/src/runtime.ts:254),所以命令行产品同样受这两处约束。
同一天的配套提交 30dd6f27f1b0 改写了 docs/telemetry.md,并让 mcode telemetry status 列出三个通道。更新日志却没跟上:中文更新日志 0.2.5 仍写着“TUI 会在本地有界保存经过脱敏的异常退出与生命周期故障信息,并在登录后自动上报”(packages/tui/CHANGELOG.zh-CN.md:388),这句话已不符合现在的代码,后面的版本也没有记这次改动。
使用事件
- 白名单:只有 10 种事件,每种只取固定的几个属性,其余一概丢弃(
EVENT_PROPERTY_KEYS,business-telemetry.ts:111)。每条都附surface、os、region、build_env、app_version五个公共字段。 - 没有持久身份:
$identity_cookie_id与distinct_id每条事件现生成一个 UUID(business-telemetry.ts:222),只为满足接收端要求的信封格式,两条事件之间无法据此关联。 - 只在内存里排队:最多 100 条,满了丢最旧的(
business-telemetry.ts:184);在微任务里逐条 POST,每条 3 秒超时,失败直接吞掉;退出时flush()一次。 - 编码:请求体是表单,
data为 Base64 编码的 JSON,ext为crc=加一个 Java 风格的字符串哈希(business-telemetry.ts:266)。
TUI 这边的取值:chat_type 在会话里有子 Agent 时报 agent_team,否则报 chat(packages/tui/src/tui/app-composition.ts:514);@ 菜单的点击只会报 file 或 directory,类型定义里的其余几种取值 TUI 用不到(packages/tui/src/analytics/tui-business-event-tracker.ts:84);tui_launch 在首帧画出后报 cold,从挂起恢复时报 hot(launcher.ts:547)。命令行的 mcode login 不传遥测客户端,走那条路登录不产生事件(packages/tui/src/cli/auth-command.ts:75)。
错误诊断与本地记录
诊断相关的本地文件都在数据目录的 v2/observability 下:
| 子目录 | 内容 | 会不会上传 |
|---|---|---|
cli/incidents | TUI 事故记录(incident-reporter.ts:130) | 同意诊断且已登录时批量上传 |
mcode | TUI 观测日志:启动各阶段耗时、终端画像、主题探测、事件流重连、进程停止原因,保留 7 天(packages/tui/src/observability/local-observability.ts:168) | 不自动上传 |
logs | 运行时日志(packages/tui/src/runtime/logging.ts:41) | 不自动上传 |
三类文件都会在用户主动 /feedback 时以计数形式进入诊断包(只留本地的事故记录也算在内),见文末。观测日志里预留了采样渲染耗时的 observeRender(),但公开源码里没有任何调用方。
TUI 事故记录器的流程:
要点:
- 记什么:9 种事件类型,从启动失败、渲染失败、运行时桥接错误到上次非正常退出(
TuiIncidentEventType,incident-reporter.ts:20)。只留固定的类别、阶段、严重度、错误名与错误码、HTTP 状态、最多 20 个预定义的面包屑,自由文本、堆栈、调用方上下文一概不收;具体字段见docs/tui-capabilities.md的“Diagnostic upload privacy”。 - 限流:每次运行最多 100 条非致命事故,同一指纹 60 秒内去重(致命事故 2 秒);目录里最多留 200 个文件、7 天(
incident-reporter.ts:136),清理时先删local-,再删sent-,最后才动pending-。 - 非正常退出:启动时写一个
active-开头的标记文件,正常结束时删掉;下次启动若发现对应进程已不在,就补记一条cli_unclean_exit(incident-reporter.ts:457)。 - 上传:只读
pending-开头的文件(incident-reporter.ts:743),发送前重新做一遍最小化;事件日志用 AES-256-GCM 加密,密钥由访问令牌经 HKDF 派生,用户 ID 作为 HKDF 的 info 参数(incident-reporter.ts:715);请求带 Bearer 令牌,URL 上带user_id,单次 10 秒超时,退出时最多再等 300 毫秒。
所以即便内容已经最小化、又做了加密,这个通道仍然是绑定账号的,docs/telemetry.md 也这样写。另一个小差别是国内区的主机:TUI 事故发往 agent.minimaxi.com(incident-reporter.ts:151),LLM 失败报告发往 agent.minimax.cn(packages/local-runtime/src/error-reporting/matrix-api-client.ts:51),路径相同;文档只笼统说“regional MiniMax host”。LLM 失败报告本身只接受 llm_request_failure 一种事件,明文超过 16 KiB 的直接丢弃,不截断(reporter.ts:123)。
自更新
启动检查的入口在 app.start()(packages/tui/src/tui/app.ts:790),更新模块按需动态加载,结果只用来在欢迎页显示一个新版本号(packages/tui/src/update/startup-notice.ts:7)。真正的逻辑在 McodeUpdateApplication(packages/tui/src/update/application.ts:141),先判断这份 mcode 是怎么装上的(packages/tui/src/update/install-source.ts:75):
| 安装来源 | 怎么认出来 | 怎么升级 |
|---|---|---|
| 官方安装器 | 安装根目录的 install.json 里 updateOwner 为 mcode-installer | 拉签名清单,下载校验后装进新版本目录 |
| npm 前缀 | 前缀下的 install.json 回执写着 npm-prefix,或前缀目录名为 .minimax-code 且 Node 所在目录里有 npm | 在暂存目录里 npm install,校验后切换指针 |
| pnpm、yarn、bun 全局 | 包路径匹配各自的全局目录 | 运行对应的全局安装命令 |
| npm 全局 | 包路径等于 npm prefix --global 下的位置 | npm install --global |
| 认不出 | 以上都不是 | 只打印手动升级命令 |
官方安装器的安装根取 MCODE_INSTALL_ROOT;没设时,Windows 上是 LOCALAPPDATA 下的 MinimaxCode,其他平台是 XDG_DATA_HOME(缺省为主目录下的 .local/share)下的 minimax-code(packages/tui/src/update/service.ts:260)。升级时:
- 按
update.json选渠道(stable或preview,缺省stable),并行下载channels/<渠道>.json与同名的.sig,8 秒超时(service.ts:103)。清单地址的缺省值是一个阿里云 OSS 路径(service.ts:25)。 - 用
install.json里记的公钥(或MCODE_RELEASE_PUBLIC_KEY_FILE指定的文件)调crypto.verify(null, …)验签,算法由公钥类型决定(packages/tui/src/update/release.ts:69);再核对渠道、版本与当前平台是否有包。 - 下载安装包,比对大小与 SHA-256(
service.ts:434),在versions目录下的暂存目录里安装、验证版本号,改名为以版本号命名的目录,最后改写current文件(service.ts:447)。任何一步失败都删掉暂存目录,旧版本不动。
npm 前缀安装走类似的“暂存、校验、切指针”:在前缀的 releases 目录下建一个暂存目录执行 npm install,版本和入口都验过之后改名为以版本号命名的目录,最后原子地写入 current,代码注释称之为提交点(packages/tui/src/update/versioned-prefix.ts:119)。npm 的安装命令都带 --ignore-scripts=false --include=optional --allow-scripts=<包名>,better-sqlite3 与显式的 --registry(install-source.ts:201),与 README 的安装命令一致。包管理器类的来源在每次启动检查时都要跑一次 npm view <包>@<标签> version --json 查最新版本(install-source.ts:276)。
TUI 里的 /update 还多一道闸:当前会话有回合在跑、有排队消息、有待回答的提问或待处理的审批时一律不让升级(packages/tui/src/tui/controller/product/update-admission.ts:17)。
签到
/checkin 先确认已登录,没登录就先弹登录,登录完接着签到(packages/tui/src/tui/controller/product/command-flow.ts:1449)。之后由 TuiDailyCheckinApplication 执行,同一时刻只跑一个请求(packages/tui/src/checkin/application.ts:34):先 GET /minimax-cloud/api/v1/signin/status 取七天的签到面板,今天已签就直接返回,没有可签的日子就报暂不可用,否则 POST /minimax-cloud/api/v1/signin/claim(packages/tui/src/checkin/http-gateway.ts:17)。网关请求 30 秒超时,遇到 401 强制刷新令牌重试一次;两次请求之间若换了账号就中止,提示重试。
packages/shared/src/daily-signin.ts 是这套协议的共享定义:天的状态、领取结果、面板场景三个枚举,面板与领取结果的校验(必须正好 7 天、编号 1 到 7 不重复、可领取与“今天”各至多一天,daily-signin.ts:92),以及连签天数的计算(daily-signin.ts:70)。它放在跨产品共用的 shared 包里,但公开源码中只有 TUI 的签到模块引用它;界面上的输出是“Checked in: Cycle day N, +P Credits”加一行本周期的 ✓ 与 · 进度(packages/tui/src/checkin/presentation.ts:11)。
诊断命令
| 入口 | 看什么 |
|---|---|
/doctor | 只读的配置检查:config.yaml 是否有效、路径、文件在不在;有效时显示默认模型与提供方,否则列出问题、影响与下一步(packages/tui/src/tui/features/inspection/product-inspection.ts:366) |
/status | 版本、模型与推理强度、账号、Token Plan 的 5 小时与每周额度、权限模式、Git 信息、生效的指令文件 |
/context | 运行时上下文快照,按系统提示词、记忆、工具、技能、消息、其他分别统计 token(packages/tui/src/tui/transcript/model.ts:75) |
/usage | 本会话的输入输出 token、缓存命中与上下文占用 |
/feedback | 需登录;先预览再提交,附带一个诊断包 |
mcode telemetry status | 三个遥测通道的生效状态 |
/feedback 的诊断包从当前会话的记录,以及最近两天的运行时日志、观测日志、运行时事件、CLI 日志与事故记录里收集(packages/tui/src/runtime/feedback/diagnostic-upload.ts:198),但每个文件只留角色、状态、错误类型、日志级别、HTTP 状态这类计数,文件名换成不透明的编号,策略名为 diagnostic-counts-v1(diagnostic-upload.ts:134)。反馈文字本身会发送出去,只去掉控制字符并把识别出的凭据打码(packages/tui/src/runtime/feedback/ticket.ts:177)。这样的包没法用来复现具体的回答或看原始堆栈,docs/tui-capabilities.md 对此有明确说明。
与文档对照
docs/telemetry.md 与代码基本一致:默认全关、逐项同意、环境变量优先、未同意时事故只留本地且 LLM 报告在缓冲前丢弃,都能在代码里对上。几处文档没写或写得笼统的地方:
- 运行时指标除了
telemetry.metrics,还要求是托管运行时(host-metrics.ts:112);mcode telemetry status只按配置与环境变量报告,不反映这一层,也不反映是否已登录。 - 国内区两类诊断发往不同的主机,见上文。
- 中文更新日志 0.2.5 那句“登录后自动上报”已经过时。
docs/tui-capabilities.md说更新“public packages use public npm”,这对 npm 类安装成立;官方安装器那条路拉的是 OSS 上的签名清单,安装包地址写在清单里。
下一篇:回顾——把前面各部分串起来再看一遍。