首页
/ Astro 匿名遥测(Telemetry)完全指南:`@astrojs/telemetry` 的工作原理与关闭方法

Astro 匿名遥测(Telemetry)完全指南:`@astrojs/telemetry` 的工作原理与关闭方法

2026-09-07 11:39:57作者:滑思眉Philip

导读

Astro 官方在 CLI 中内置了一套匿名遥测(telemetry)系统,用于收集“Astro 以何种方式、在何种环境中被使用”的统计信息,帮助团队排定功能与修复的优先级。这套能力以独立包 @astrojs/telemetry 形式实现,其设计核心是匿名性与可随时关闭。本文以 packages/telemetry/README.md 为骨架,结合 packages/telemetry 下的源码与测试,讲清楚三件事:Astro 到底收集了什么、数据如何被打包上传、以及开发者如何用官方提供的方式彻底关闭遥测。

遥测是什么:一个内置于 Astro CLI 的匿名统计模块

遥测(telemetry)是"自动采集与回传匿名使用数据"的机制。Astro 把遥测封装为独立的 npm 包 @astrojs/telemetry,其定位在 README 中写得很明确:

This package is used to collect anonymous telemetry data within the Astro CLI.

即:该包只为 Astro CLI 服务,采集的是"匿名"遥测数据,而非包含个人身份信息的数据。对应的发布信息可以在 packages/telemetry/package.json 中看到:包名为 @astrojs/telemetry,当前仓库中的版本为 3.3.3,采用 ESM("type": "module"),产物入口为 dist/index.js

它在 Astro 主包中通过 packages/astro/src/events/index.ts 被实例化并复用,例如以 new AstroTelemetry({ astroVersion, viteVersion }) 的方式注入当前运行环境的版本信息,随后 CLI 的各个命令(devbuildsyncadd 等)都会引用这个单例来上报事件。

关闭遥测的两种官方方式(README 核心内容)

@astrojs/telemetry 的 README 虽然简短,但给出了两个明确可执行的关闭方法,这也是绝大多数用户最关心的部分。以下两条命令/配置直接继承自 README,属于官方推荐的全部关闭途径:

方式一:全局永久关闭

在终端中执行一次即可,配置会写入你的用户级配置,效果作用于整台机器上的所有 Astro 项目:

# Option 1: Run this to disable telemetry globally across your entire machine.
astro telemetry disable

该命令等价于调用 AstroTelemetry.setEnabled(false),把 telemetry.enabled 置为 false 并持久化(见下文"配置存储在哪里"一节)。源码中的子命令入口在 packages/astro/src/cli/telemetry/index.ts,它实际支持三个子命令:

子命令 说明 底层行为
astro telemetry enable 重新开启匿名数据收集 telemetry.setEnabled(true)
astro telemetry disable 关闭匿名数据收集 telemetry.setEnabled(false)
astro telemetry reset 重置匿名数据收集设置 telemetry.clear(),清空全部遥测相关配置

方式二:环境变量按次关闭

如果你只想在某一次运行中关闭遥测、而不想改动全局配置,可以设置环境变量:

# Option 2: The ASTRO_TELEMETRY_DISABLED environment variable disables telemetry when set.
ASTRO_TELEMETRY_DISABLED=1 astro dev

ASTRO_TELEMETRY_DISABLED 存在(非空)时,本次进程内的遥测即被禁用。从 packages/telemetry/src/index.tsisDisabled 实现看,判断顺序为:

private get isDisabled(): boolean {
	if (Boolean(this.ASTRO_TELEMETRY_DISABLED || this.TELEMETRY_DISABLED)) {
		return true;
	}
	return this.enabled === false;
}

这里有两点值得注意的源码级细节:

  1. 该判断同时兼容 ASTRO_TELEMETRY_DISABLED 与更通用的 TELEMETRY_DISABLED 两个环境变量,二者任一被设置都会立即关闭遥测;
  2. 环境变量的优先级高于持久化配置——即使全局配置里 telemetry.enabled 仍为 true,只要本次运行设置了该环境变量,本次进程也不会发送任何遥测数据。

由于 README 中还有一行提示(请访问 astro.build/telemetry/ 了解匿名遥测的整体策略),若需查看更多关于该机制的设计说明,可继续阅读本包源码目录 packages/telemetry/src

遥测在首次运行时如何征得同意:notify 机制

在你第一次运行某些 Astro 命令时,终端会出现一条遥测相关的提示(如"Astro 希望收集匿名使用数据"),你可以在其中选择允许或拒绝。这一流程对应的正是 AstroTelemetry.notify()

async notify(callback: () => boolean | Promise<boolean>) {
	// 已禁用或处于 CI 环境则直接跳过提示
	if (this.isDisabled || this.isCI) {
		return;
	}
	// 已经提示过就不再打扰
	if (this.isValidNotice()) {
		return;
	}
	const enabled = await callback();
	this.config.set(KEY.TELEMETRY_NOTIFY_DATE, new Date().valueOf().toString());
	this.config.set(KEY.TELEMETRY_ENABLED, enabled);
}

notify() 由 CLI 侧调用,见 packages/astro/src/cli/telemetry/index.ts 中的 notify()(打印提示后返回 true,即默认同意)。需要理解的设计要点:

  • 只询问一次:用户做出选择后,telemetry.notifiedAt 会被记录为当前时间戳。代码中的 VALID_TELEMETRY_NOTICE_DATE = '2023-08-25' 是一个"策略有效期"边界,只有之前提示日期晚于该边界才认为提示已生效,避免策略大幅变更后用户仍不知情。
  • CI 环境中不打扰:在 CI 里 notify 直接返回,避免自动化流水线被交互提示阻塞。

数据从哪里来:配置持久化与"匿名 ID"的生成

配置存储在哪里

AstroTelemetry 内部通过 GlobalConfig 读取/写入用户级配置,其文件路径跟随操作系统规范(见 packages/telemetry/src/config.ts):

操作系统 配置文件路径(name = astro
macOS ~/Library/Preferences/astro/config.json
Windows %APPDATA%/astro/Config/config.jsonAPPDATA 未设置时回退到 ~/AppData/Roaming
Linux 及其他 $XDG_CONFIG_HOME/astro/config.json(未设置时回退到 ~/.config

GlobalConfig 以"点路径 + dset"的方式读写嵌套键,并支持 get / set / has / delete / clear 等操作。Astro 遥测在全局配置中实际使用的键定义在 packages/telemetry/src/config-keys.ts

  • telemetry.enabled:遥测总开关(true / false);
  • telemetry.notifiedAt:用户被告知匿名遥测的时间戳;
  • telemetry.anonymousId:用于"按用户去重"的匿名标识符。

"匿名"是如何实现的:随机 ID 与项目哈希

所谓匿名,关键在于两个标识符的生成方式(见 packages/telemetry/src/index.tsproject-info.ts):

  • anonymousId(用户级):首次使用时由 randomBytes(32).toString('hex') 生成 64 位十六进制随机串,并持久化到全局配置中;
  • anonymousSessionId(会话级):每次进程内按同样方式生成,不落盘,仅标识"这一次运行";
  • anonymousProjectId(项目级):核心逻辑在 getProjectIdFromGit()——优先对仓库执行 git rev-list --max-parents=0 HEAD 取首个提交哈希,再做一次 SHA-256 哈希得到匿名项目标识。

project-info.ts 的注释对隐私边界做了非常坦诚的说明,可概括为:

  • 该哈希不使用仓库 remote URL、GitHub 地址等任何可识别个人的信息;
  • 若运行目录不在 git 仓库内,则退化为对当前工作目录绝对路径做 SHA-256 哈希;
  • 若处于 CI 环境或目录层级过浅(如 /app),则不生成项目 ID,返回 undefined
  • 私有仓库的项目 ID 无法被回溯;公开仓库理论上他人可通过 clone 后自行 git rev-list 得到同一哈希,因此它只能证明"项目是同一个",并不能定位到个人;
  • 想彻底关闭该收集行为,唯一途径就是关闭整个遥测(astro telemetry disable)。

CI 场景的去重策略

源码还处理了一个数据质量问题:CI 中每次运行都会"新建用户"从而污染统计。因此在检测到 CI 环境时,会把 anonymousId 强制替换为统一的 CI.{ciName || 'UNKNOWN'} 形式,使同一 CI 平台(如 GitHub Actions、Travis)的多次运行被聚合为单一匿名用户(见 packages/telemetry/src/index.tsrecord() 的 CI 分支)。

一条遥测事件从产生到发出的完整链路

telemetry.record([{ eventName: 'astro:build', payload: {...} }]) 为例,一次上报经历的步骤(全部实现于 packages/telemetry/src/index.tsrecord()):

  1. 开关检查:先判断 isDisabled,禁用时直接 return,不产生任何网络请求;
  2. 组装 meta:调用 getSystemInfo() 收集运行环境信息(见下节);
  3. 组装 context:合并项目级匿名 ID、用户级匿名 ID、会话 ID;
  4. 调试模式短路:若进程设置了 DEBUG 且包含 astro:telemetry / astro:* / *,则仅把 contextmeta 与完整事件 JSON 打印到 stderr,并不真正发送。官方注释指出这正是一个"预览将要发送什么数据"的调试入口;
  5. 发送:调用 post(),把 { context, meta, events } 以 JSON 形式 POST 到遥测服务端。请求地址与内容类型定义在 post.tshttps://telemetry.astro.build/api/v1/recordcontent-type: application/json。任何发送失败(网络错误等)只会进入 debug 日志,不会影响你的正常开发流程——这是刻意为之的健壮性设计。

遥测数据的边界:收集什么、不收集什么

需要强调的是,发送的 meta(由 getSystemInfo() 产生,见 packages/telemetry/src/system-info.ts)全部是运行环境与机器资源的客观信息,且不包含任何个人可识别信息:

  • 版本信息nodeVersionviteVersionastroVersion
  • 系统信息systemPlatform(操作系统平台)、systemRelease(系统版本)、systemArchitecture(CPU 架构);
  • 硬件信息cpuCountcpuModelcpuSpeedmemoryInMb(总内存);
  • 环境信息isDocker(是否运行在容器中)、isTTY(是否为交互式终端)、isWSL(是否 Windows Subsystem for Linux)、isCIciName(是否/何种 CI 平台)。

其中 isCI / ciNameci-info 库判定,isDockeris-docker 判定,均为仓库 package.json 中声明的真实依赖。system-info.ts 的注释同样明确了边界:系统信息本身不含个人身份信息,仅凭系统信息通常无法唯一定位某一台个人机器。

一句话总结边界:Astro 遥测关心的是"什么平台 + 什么版本 + 跑在什么机器规格上 + 是否 CI/容器",而不关心"你是谁、你的项目叫什么、代码里有什么"。

如何在终端确认或调试遥测

基于源码,你可以用以下几种方式把遥测行为"看清楚":

  • 查看当前是否禁用:直接执行 astro telemetry disable 后再操作并不会看到再次询问——因为 telemetry.enabled 已持久化为 false。想恢复则执行 astro telemetry enable,想重置全部遥测设置则执行 astro telemetry reset
  • 预览将要发送的数据:以 DEBUG=astro:telemetry 前缀运行任意 Astro 命令,遥测模块会把 contextmeta 与事件 JSON 完整打印到标准错误输出,同时跳过实际上传,可用于核对数据内容是否如本文所述;
  • 核对开关优先级:无论全局配置为何值,ASTRO_TELEMETRY_DISABLED=1TELEMETRY_DISABLED=1 都会让当前进程完全静默。

这些开关行为在 packages/telemetry/test/index.test.ts 中均有自动化测试覆盖(例如 stub process.env 后断言 isDisabled 为真、record() 返回空且不发送),若想深入理解语义,该测试文件是很好的参考。

相关文件索引

登录后查看全文
热门项目推荐
相关项目推荐