Go 官方博客

Go 1.23 及更高版本中的遥测功能

Robert Findley
2024 年 9 月 3 日

Go 1.23 提供了一种新的方式来帮助改进 Go 工具链。通过启用遥测数据上传,您可以选择与 Go 团队分享有关工具链程序及其使用情况的数据。这些数据将帮助 Go 贡献者修复错误、避免回归并做出更好的决策。

默认情况下,Go 遥测数据仅存储在您的本地计算机上。如果您启用上传,每周会将您的数据中的有限子集发布到 telemetry.go.dev

从 Go 1.23 开始,您可以使用以下命令启用本地遥测数据上传

go telemetry on

要禁用甚至本地遥测数据收集,请运行以下命令

go telemetry off

遥测文档包含更详细的实现说明。

Go 遥测的简要历史

虽然软件遥测不是一个新概念,但 Go 团队经过多次迭代,寻找一种满足 Go 对性能、可移植性和透明性要求的遥测实现。

最初的设计旨在做到非常不显眼、开放和隐私保护,以便默认启用是可接受的,但在冗长的公开讨论中,许多用户提出了担忧,最终该设计被更改为要求用户明确同意才能进行远程上传。

新设计于 2023 年 4 月被接受,并在那个夏天进行了实施。

gopls 中的遥测

Go 遥测的首次迭代随 Go 语言服务器 goplsv0.14 版本于 2023 年 10 月发布。发布后,大约 100 名用户启用了上传,他们可能是受发布说明或 Gophers Slack 频道讨论的启发,数据开始缓慢传入。不久后,遥测就在 gopls 中发现了它的第一个错误

Telemetry found its first bug
Dan 在他上传的遥测数据中注意到的一份堆栈跟踪报告导致一个错误被报告并修复。值得指出的是,我们完全不知道是谁报告了这份堆栈。

IDE 提示

虽然很高兴看到遥测在实践中发挥作用,并且我们感谢早期采用者的支持,但 100 名参与者不足以衡量我们想要衡量的事物类型。

正如 Russ Cox 在他最初的博客文章中指出的那样,默认关闭遥测的一个缺点是需要持续鼓励参与。维持一个足够大以进行有意义的定量数据分析且代表用户群体的用户样本需要进行推广。虽然博客文章和发布说明可以提高参与度(如果您在阅读本文后启用遥测,我们将不胜感激!),但它们会导致样本偏差。例如,我们从 gopls 遥测的早期采用者那里几乎没有收到关于 GOOS=windows 的数据。

为了帮助覆盖更多用户,我们在 VS Code Go 插件中引入了一个提示,询问用户是否要启用遥测

The VS Code prompt
VS Code 显示的遥测提示。

截至本博客文章发布时,该提示已向 5% 的 VS Code Go 用户推出,遥测样本已增长到每周约 1800 名参与者

Weekly Uploads vs Prompt Rate
提示有助于覆盖更多用户。

(最初的增加可能是由于提示了 VS Code Go nightly 扩展的所有用户所致)。

然而,与最近的 Go 调查结果相比,这导致样本明显偏向 VS Code 用户

Skew toward VS Code users
我们怀疑 VS Code 在遥测数据中的代表性过高。

我们计划通过利用语言服务器协议本身的一个功能,提示所有使用 gopls 的支持 LSP 的编辑器来解决这种偏差。

遥测的成功

出于谨慎考虑,我们建议在 gopls 遥测首次发布时仅收集少数基本指标。其中之一是 gopls/bug 堆栈计数器,它记录 gopls 遇到的意外或“不可能”的情况。实际上,它是一种断言,但它不会停止程序,而是在遥测中记录在某些执行中达到了该状态,并附带堆栈信息。

在我们的 gopls 可伸缩性工作中,我们添加了许多此类断言,但我们很少在测试或我们自己使用 gopls 时观察到它们失败。我们曾预期几乎所有这些断言都是无法达到的。

当我们开始提示 VS Code 中的随机用户启用遥测时,我们发现许多这些条件在实践中确实被触发了,而且堆栈跟踪的上下文通常足以让我们重现并修复长期存在的错误。我们开始将这些问题归类在 gopls/telemetry-wins 标签下,以记录遥测带来的“成功”。

我开始从另一个角度理解“遥测的成功”:当比较使用遥测和不使用遥测的 gopls 开发时,遥测更胜一筹

Telemetry wins.
感谢 Paul 的建议。

从遥测数据中发现的错误最令人惊讶的一点是,其中有多少是真实存在的。当然,其中一些对用户来说是不可见的,但 상당 部分是 gopls 的实际错误行为——例如缺失交叉引用,或在某些罕见条件下微妙不准确的补全。它们正是那种用户可能只会轻微恼火但可能不会费心报告为问题的事物。也许用户会认为这种行为是故意的。如果他们确实报告了一个问题,他们可能不确定如何重现该错误,或者我们需要在问题跟踪器上进行长时间的来回沟通才能捕获堆栈跟踪。没有遥测,几乎没有合理的方法能够发现这些错误,更不用说修复了。

而这一切仅仅来自于几个计数器。我们只针对我们已知的潜在错误进行了堆栈跟踪的检测。那么我们没有预料到的问题呢?

自动崩溃报告

Go 1.23 包含一个新的 runtime.SetCrashOutput API,可用于通过守护进程实现自动崩溃报告。从 v0.15.0 开始,当 gopls 崩溃时,它会报告一个 crash/crash 堆栈计数器,前提是 gopls 本身是使用 Go 1.23 构建的

当我们发布 gopls@v0.15.0 时,样本中只有少数用户使用未发布的 Go 1.23 开发版本构建了 gopls,然而新的 crash/crash 计数器仍然发现了两个错误

Go 工具链及更高版本中的遥测

考虑到遥测仅用少量工具检测和部分目标样本就已证明其有用性,未来前景光明。

Go 1.23 在 Go 工具链内部记录遥测数据,包括 go 命令以及编译器、链接器和 go vet 等其他工具。我们已将遥测添加到 vulncheck 和 VS Code Go 插件中,并且我们提议将其添加到 delve 中。

最初的遥测博客系列集思广益了许多关于如何利用遥测改进 Go 的想法。我们期待着探索这些想法以及更多内容。

在 gopls 内部,我们计划使用遥测来提高可靠性并为决策和优先级排序提供信息。通过 Go 1.23 启用的自动崩溃报告,我们预计在预发布测试中捕获更多崩溃。展望未来,我们将添加更多计数器来衡量用户体验——关键操作的延迟、各种功能的使用频率——以便我们可以将精力集中在最能使 Go 开发者受益的地方。

今年 11 月,Go 将迎来 15 岁生日,Go 语言及其生态系统持续增长。遥测将在帮助 Go 贡献者更快、更安全地朝着正确方向前进方面发挥关键作用。

下一篇文章:分享您使用 Go 开发的反馈
上一篇文章:新的 unique 包
博客索引