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 1.23 或更高版本,要選擇啟用向 Go 團隊上傳遙測資料,請執行
go telemetry on
要完全停用遙測,包括本地收集,請執行
go telemetry off
要恢復到預設的僅本地遙測模式,請執行
go telemetry local
在 Go 1.23 之前,也可以使用 golang.org/x/telemetry/cmd/gotelemetry 命令完成此操作。有關更多詳細資訊,請參閱配置

概覽

Go 遙測使用三種核心資料型別

  • 計數器是工具鏈程式中記錄的命名事件的輕量級計數。如果啟用了收集(模式localon),計數器將寫入本地檔案系統中的記憶體對映檔案。
  • 報告是給定周內計數器的彙總摘要。如果啟用了上傳(模式on),經批准的計數器的報告將上傳到 telemetry.go.dev,並在那裡公開訪問。
  • 圖表彙總了所有使用者上傳的報告。圖表可以在 telemetry.go.dev 上檢視。

所有本地 Go 遙測資料和配置都儲存在 os.UserConfigDir()/go/telemetry 目錄中。下面,我們將此目錄稱為 <gotelemetry>

下圖展示了此資料流。

在本文的其餘部分,我們將探討此圖表的元件。但首先,讓我們瞭解更多控制它的配置。

配置

Go 遙測的行為由一個值控制:遙測模式mode 的可能值為 local(預設)、onoff

  • modelocal 時,遙測資料被收集並存儲在本地計算機上,但從不上傳到遠端伺服器。
  • modeon 時,資料被收集,並可能根據取樣進行上傳。
  • modeoff 時,資料既不收集也不上傳。

使用 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:neovimgopls/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

這些檔案被記憶體對映到每個正在執行的被檢測程式例項中。使用記憶體對映檔案意味著即使程式立即崩潰,或者幾個被檢測工具的副本同時執行,計數器也能安全地記錄下來。

報告和上傳

大約每週一次,計數器資料會被聚合到 <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.org.tw/issue/61038
issue: https://golang.org.tw/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 上呈現的聚合來表達的,其原則是:我們只收集我們希望看到的資料。

提案流程如下

  1. 提案人建立 CL,修改 config.txtchartconfig 包,以包含所需的新計數器聚合。
  2. 提案人提交提案以合併此 CL。
  3. 一旦問題討論解決,提案將由 Go 團隊成員批准或拒絕。
  4. 一個自動過程會重新生成上傳配置,以允許上傳新圖表所需的計數器。此過程還將隨著相關程式的釋出定期向上傳配置新增新版本。

為了獲得批准,新圖表不能包含敏感的使用者資訊,並且必須既有用又可行。為了有用,圖表必須服務於特定目的,並具有可操作的結果。為了可行,必須能夠可靠地收集所需資料,並且結果測量必須具有統計顯著性。為了證明可行性,提案人可能被要求首先用計數器檢測目標程式並進行本地收集。

所有此類提案的完整集合可在 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 遙測的原始碼在哪裡?

答:在 golang.org/x/telemetry