Go 遥测
目录
背景
概述
配置
计数器
报告和上传
图表
遥测提案
IDE 提示
常见问题解答
背景
Go 遥测是 Go 工具链程序收集其性能和使用情况数据的一种方式。此处“Go 工具链”指的是由 Go 团队维护的开发者工具,包括 go
命令和补充工具,例如 Go 语言服务器 gopls
或 Go 安全工具 govulncheck
。Go 遥测仅用于 Go 团队维护的程序及其选定的依赖项(如 Delve)。
默认情况下,遥测数据仅保留在本地计算机上,但用户可以选择将经过批准的遥测数据子集上传到 telemetry.go.dev。上传的数据有助于 Go 团队改进 Go 语言及其工具,帮助我们了解使用情况和故障。
在开源软件领域,“遥测”一词已产生负面含义,在许多情况下这种含义是当之无愧的。然而,衡量用户体验是现代软件工程的重要组成部分,而 GitHub 问题或年度调查等数据来源是粗略且滞后的指标,不足以回答 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
堆栈计数器,它计算程序员预先识别的异常情况,例如恢复的恐慌或“不可能发生”的错误。堆栈计数器仅包含 Go 工具链程序中函数的名称和行号。它们不包含有关用户输入的任何信息,例如用户源代码的名称或内容。
堆栈计数器可以帮助跟踪难以发现的罕见错误,这些错误无法通过其他方式报告。自从引入 gopls/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://golang.ac.cn/issue/61038
issue: https://golang.ac.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 上呈现的聚合形式表达的,其原则是我们只收集我们想要查看的数据。
提案流程如下所示
- 提案者创建了一个修改 config.txt 的 CL,该文件属于 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 遥测的源代码在哪里?