Go 遥测
目录
背景
概览
配置
计数器
报告和上传
图表
遥测提案
IDE 提示
常见问题
背景
Go 遥测是 Go 工具链程序收集其性能和使用情况数据的一种方式。这里的“Go 工具链”指的是 Go 团队维护的开发工具,包括 go
命令和补充工具,如 Go 语言服务器 gopls
或 Go 安全工具 govulncheck
。Go 遥测仅限于 Go 团队维护的程序及其选定的依赖项(如 Delve)使用。
默认情况下,遥测数据仅保留在本地计算机上,但用户可以选择上传经批准的遥测数据子集到 telemetry.go.dev。上传的数据有助于 Go 团队通过了解使用情况和故障来改进 Go 语言及其工具。
“遥测”这个词在开源软件领域已经获得了一些负面含义,在许多情况下是理所当然的。然而,衡量用户体验是现代软件工程的一个重要元素,而像 GitHub issue 或年度调查这样的数据源是粗略和滞后的指标,不足以回答 Go 团队需要回答的问题。Go 遥测旨在帮助工具链中的程序收集有关其可靠性、性能和使用情况的有用数据,同时保持用户对 Go 项目所期望的透明度和隐私。要了解有关遥测设计过程和动机的更多信息,请参阅遥测博客文章。要了解有关遥测和隐私的更多信息,请参阅遥测隐私政策。
本页详细解释了 Go 遥测的工作原理。有关常见问题的快速解答,请参阅常见问题。
go telemetry on要完全禁用遥测,包括本地收集,请运行
go telemetry off要恢复到默认的仅本地遥测模式,请运行
go telemetry local在 Go 1.23 之前,也可以使用
golang.org/x/telemetry/cmd/gotelemetry
命令完成此操作。有关更多详细信息,请参阅配置。概览
Go 遥测使用三种核心数据类型
- 计数器是工具链程序中记录的命名事件的轻量级计数。如果启用了收集(模式为 local 或 on),计数器将写入本地文件系统中的内存映射文件。
- 报告是给定周内计数器的汇总摘要。如果启用了上传(模式为 on),经批准的计数器的报告将上传到 telemetry.go.dev,并在那里公开访问。
- 图表汇总了所有用户上传的报告。图表可以在 telemetry.go.dev 上查看。
所有本地 Go 遥测数据和配置都存储在 os.UserConfigDir()/go/telemetry
目录中。下面,我们将此目录称为 <gotelemetry>
。
下图展示了此数据流。

在本文的其余部分,我们将探讨此图表的组件。但首先,让我们了解更多控制它的配置。
配置
Go 遥测的行为由一个值控制:遥测模式。mode
的可能值为 local
(默认)、on
或 off
- 当
mode
为local
时,遥测数据被收集并存储在本地计算机上,但从不上传到远程服务器。 - 当
mode
为on
时,数据被收集,并可能根据采样进行上传。 - 当
mode
为off
时,数据既不收集也不上传。
使用 Go 1.23 或更高版本,以下命令与遥测模式交互
go telemetry
:查看当前模式。go telemetry on
:将模式设置为on
。go telemetry off
:将模式设置为off
。go telemetry local
:将模式设置为local
。
遥测配置信息也可以通过只读 Go 环境变量获取
go env GOTELEMETRY
报告遥测模式。go env GOTELEMETRYDIR
报告存储遥测配置和数据的目录。
gotelemetry
命令也可用于配置遥测模式,以及检查本地遥测数据。使用此命令安装它
go install golang.org/x/telemetry/cmd/gotelemetry@latest
有关 gotelemetry
命令行工具的完整用法信息,请参阅其包文档。
计数器
如上所述,Go 遥测通过计数器进行测量。计数器有两种变体:基本计数器和栈计数器。
基本计数器
基本计数器是一个可递增的值,其名称描述了它计数的事件。例如,gopls/client:vscode
计数器记录了 VS Code 启动 gopls
会话的次数。除了这个计数器,我们可能还有 gopls/client:neovim
、gopls/client:eglot
等,用于记录与不同编辑器或语言客户端的会话。如果你在一周内使用了多个编辑器,你可能会记录以下计数器数据
gopls/client:vscode 8
gopls/client:neovim 5
gopls/client:eglot 2
当计数器以这种方式相关联时,我们有时将 :
之前的部分称为图表名称(本例中为 gopls/client
),将 :
之后的部分称为桶名称(vscode
)。当我们讨论图表时,我们将看到这为什么很重要。
基本计数器也可以表示直方图。例如,gopls/completion/latency:<50ms
计数器记录了自动完成耗时小于 50 毫秒的次数。
gopls/completion/latency:<10ms gopls/completion/latency:<50ms gopls/completion/latency:<100ms ...
这种记录直方图数据的模式是一个约定:<50ms
桶名称没有什么特别之处。这些类型的计数器通常用于测量性能。
栈计数器
栈计数器是一个计数器,它在计数递增时还会记录 Go 工具链程序的当前调用栈。例如,crash/crash
栈计数器记录了工具链程序崩溃时的调用栈
crash/crash
golang.org/x/tools/gopls/internal/golang.hoverBuiltin:+22
golang.org/x/tools/gopls/internal/golang.Hover:+94
golang.org/x/tools/gopls/internal/server.Hover:+42
...
栈计数器通常测量违反程序不变性的事件。最常见的例子是崩溃,但另一个例子是 gopls/bug
栈计数器,它计算程序员预先识别的异常情况,例如已恢复的 panic 或“不可能发生”的错误。栈计数器只包括 Go 工具链程序中函数的名称和行号。它们不包含任何有关用户输入的信息,例如用户源代码的名称或内容。
栈计数器可以帮助追踪那些无法通过其他方式报告的罕见或棘手的 bug。自从引入 gopls/bug
计数器以来,我们已经发现了数十个实例的“无法到达”代码在实践中被到达,并且追踪这些异常导致了许多用户可见的 bug 的发现(和修复),这些 bug 要么对用户不明显,要么难以报告。尤其是在预发布测试中,栈计数器可以帮助我们比没有自动化的情况下更有效地改进产品。
计数器文件
所有计数器数据都写入 <gotelemetry>/local
目录,文件命名遵循以下方案
[program name]@[program version]-[go version]-[GOOS]-[GOARCH]-[date].v1.count
- 程序名称是程序包路径的基本名称,由 debug.BuildInfo 报告。
- 程序版本和 go 版本也由 debug.BuildInfo 报告。
- GOOS 和 GOARCH 值由
runtime.GOOS
和runtime.GOARCH
报告。 - 日期是计数器文件创建的日期,格式为
YYYY-MM-DD
。
这些文件被内存映射到每个正在运行的被检测程序实例中。使用内存映射文件意味着即使程序立即崩溃,或者几个被检测工具的副本同时运行,计数器也能安全地记录下来。
报告和上传
大约每周一次,计数器数据会被聚合到 <gotelemetry>/local
目录中名为 <date>.json
的报告中。这些报告汇总了前一周的所有计数,按计数器文件使用的相同程序标识符(程序名称、程序版本、Go 版本、GOOS 和 GOARCH)进行分组。
本地报告可以使用 gotelemetry view
命令以图表形式查看。以下是 gopls/completion/latency
计数器的示例摘要

上传
如果启用了遥测上传,每周的报告过程还将生成包含 上传配置中存在的计数器子集的报告。这些计数器必须经过下一节描述的公共审查流程批准。成功上传后,上传报告的副本将存储在 <gotelemetry>/upload
目录中。
一旦足够多的用户选择上传遥测数据,上传过程将随机跳过一部分报告的上传,以减少收集量并提高隐私,同时保持统计显著性。
图表
除了接受上传,telemetry.go.dev 网站还公开了上传的数据。每天,上传的报告都会处理成两个输出,这些输出可在 telemetry.go.dev 主页上获取。
- 合并报告合并了给定日期收到的所有上传的计数器。
- 图表按照 [图表配置] 中指定的方式绘制上传数据,该配置是提案过程的一部分。回顾计数器的讨论,像
foo:bar
这样的计数器名称被分解为图表名称foo
和桶名称bar
。每个图表将具有相同图表名称的计数器聚合到相应的桶中。
图表以 chartconfig 包的格式指定。例如,这是 gopls/client
图表的图表配置。
title: Editor Distribution
counter: gopls/client:{vscode,vscodium,vscode-insiders,code-server,eglot,govim,neovim,coc.nvim,sublimetext,other}
description: measure editor distribution for gopls users.
type: partition
issue: https://go-lang.org.cn/issue/61038
issue: https://go-lang.org.cn/issue/62214 # add vscode-insiders
program: golang.org/x/tools/gopls
version: v0.13.0 # temporarily back-version to demonstrate config generation.
此配置描述了要生成的图表,列举了要聚合的计数器集,并指定了图表适用的程序版本。此外,提案过程要求图表关联一个已接受的提案。这是由该配置生成的图表

遥测提案过程
对 telemetry.go.dev 上的上传配置或图表集的更改必须经过遥测提案过程,旨在确保遥测配置更改的透明度。
值得注意的是,在此过程中,上传配置和图表配置之间实际上没有区别。上传配置本身是根据我们希望在 telemetry.go.dev 上呈现的聚合来表达的,其原则是:我们只收集我们希望看到的数据。
提案流程如下
- 提案人创建 CL,修改 config.txt 的 chartconfig 包,以包含所需的新计数器聚合。
- 提案人提交提案以合并此 CL。
- 一旦问题讨论解决,提案将由 Go 团队成员批准或拒绝。
- 一个自动过程会重新生成上传配置,以允许上传新图表所需的计数器。此过程还将随着相关程序的发布定期向上传配置添加新版本。
为了获得批准,新图表不能包含敏感的用户信息,并且必须既有用又可行。为了有用,图表必须服务于特定目的,并具有可操作的结果。为了可行,必须能够可靠地收集所需数据,并且结果测量必须具有统计显著性。为了证明可行性,提案人可能被要求首先用计数器检测目标程序并进行本地收集。
所有此类提案的完整集合可在 GitHub 上的提案项目中获取。
IDE 提示
为了让遥测回答我们想要提出的问题,选择上传的用户数量不需要很多——大约 16,000 名参与者就可以在所需的粒度级别上实现统计显著的测量。然而,收集这个健康的样本仍然有成本:我们需要询问大量的 Go 开发者是否愿意选择加入。
此外,即使大量用户现在选择加入(也许在阅读 Go 博客文章后),这些用户可能会偏向有经验的 Go 开发者,随着时间的推移,初始样本将变得更加偏斜。此外,当人们更换计算机时,他们必须再次主动选择加入。在遥测博客系列文章中,这被称为选择加入模型的“宣传成本”。
为了帮助保持参与用户样本的新鲜度,Go 语言服务器 gopls
支持一个提示,询问用户是否选择加入 Go 遥测。以下是 VS Code 中的样子

如果用户选择“是”,他们的遥测模式将设置为 on
,就像他们运行了 gotelemetry on
一样。通过这种方式,选择加入变得尽可能简单,我们可以持续接触到大量且分层的 Go 开发者样本。
常见问题
问:如何启用或禁用 Go 遥测?
答:使用 gotelemetry
命令,可以通过 go install golang.org/x/telemetry/cmd/gotelemetry@latest
安装。运行 gotelemetry off
禁用所有功能,甚至本地收集。运行 gotelemetry on
启用所有功能,包括上传批准的计数器到 telemetry.go.dev。有关更多信息,请参阅配置部分。
问:本地数据存储在哪里?
答:在 os.UserConfigDir()/go/telemetry
目录中。
问:如果我选择加入,数据多久上传一次?
答:大约每周一次。
问:如果我选择加入,会上传哪些数据?
答:只有 上传配置中列出的计数器才可能被上传。这是从 [图表配置] 生成的,可能更具可读性。
问:计数器如何添加到上传配置中?
答:通过公共提案过程。
问:我在哪里可以看到已上传的遥测数据?
答:上传的数据以图表或合并摘要的形式在 telemetry.go.dev 上提供。
问:Go 遥测的源代码在哪里?