> Source: https://www.ymotongpoo.com/works/goblog-ja/gotelemetry/


# Go 1.23以降のテレメトリ

[Telemetry in Go 1.23 and beyond](https://go.dev/blog/gotelemetry) by Robert Findley

Go 1.23では、Goツールチェインの改善に協力するための新しい方法が用意されました。
[テレメトリのアップロード](https://go.dev/doc/go1.23#telemetry)を有効にすると、ツールチェインのプログラムとその
使用状況に関するデータをGoチームと共有することを選択できます。このデータは、Goのコントリビューターがバグを修正し、
リグレッションを回避し、より良い意思決定を行う助けになります。

デフォルトでは、Goのテレメトリデータはローカルコンピュータにのみ保存されます。アップロードを有効にすると、
データの[限定的な](https://go.dev/doc/telemetry#proposals)サブセットが毎週
[telemetry.go.dev](https://telemetry.go.dev)で公開されます。

Go 1.23からは、次のコマンドでローカルのテレメトリデータのアップロードを有効にできます。

```
go telemetry on
```

ローカルでのテレメトリデータの収集自体を無効にするには、次のコマンドを実行します。

```
go telemetry off
```

[テレメトリのドキュメント](https://go.dev/doc/telemetry)には実装のより詳細な説明があります。

## Goのテレメトリの歴史

ソフトウェアのテレメトリ自体は新しい発想ではありませんが、Goチームはパフォーマンス、可搬性、透明性に関するGoの
要件を満たすテレメトリの実装を求めて、何度も試行錯誤を重ねてきました。

当初の[設計](https://research.swtch.com/telemetry-design)は、デフォルトで有効にしても差し支えないほど控えめで、
オープンで、プライバシーに配慮したものを目指していましたが、[長い公開議論](https://go.dev/issue/58409)の中で
多くのユーザーから懸念の声が上がり、最終的にはリモートへのアップロードには明示的なユーザーの同意を必要とするように
設計が[変更](https://research.swtch.com/telemetry-opt-in#campaign)されました。

新しい設計は2023年4月に[承認](https://go.dev/issue/58894)され、その夏の間に実装されました。

### goplsにおけるテレメトリ

Goテレメトリの最初の実装は、2023年10月、Go言語サーバー
[`gopls`](https://go.googlesource.com/tools/+/refs/heads/master/gopls/)の
[v0.14](https://github.com/golang/tools/releases/tag/gopls%2Fv0.14.0)でリリースされました。リリース後、
リリースノートや[Gophers Slack](https://gophers.slack.com/messages/gopls/)チャンネルでの議論に触発されたのか、
およそ100人のユーザーがアップロードを有効にし、データが少しずつ集まり始めました。そして間もなく、テレメトリは
goplsの最初のバグを見つけました。

![Telemetry found its first bug](./gotelemetry/neat.png)
*Danがアップロードされたテレメトリデータの中で気づいたスタックトレースが、バグ報告と修正につながりました。
誰が報告したスタックなのか私たちには全くわかっていなかったという点は指摘しておく価値があるでしょう。*

### IDEでのプロンプト表示

テレメトリが実際に機能しているのを見られたのは素晴らしいことでしたし、初期の採用者たちの支援にも感謝していましたが、
100人の参加者では私たちが測定したい種類の物事を測るには十分ではありませんでした。

Russ Coxが[原著のブログ記事](https://research.swtch.com/telemetry-opt-in#campaign)で指摘したように、テレメトリを
デフォルトで無効にするアプローチの欠点は、参加を促すための働きかけを継続的に行う必要があることです。意味のある
定量的なデータ分析を行うのに十分な大きさで、かつユーザー集団を代表するようなサンプルを維持するには、広報活動が
必要です。ブログ記事やリリースノートは参加を後押ししてくれますが（この記事を読んでテレメトリを有効にしていただければ
幸いです）、それらは偏ったサンプルにつながります。例えば、goplsでのテレメトリの初期採用者からは、
`GOOS=windows`のデータがほとんど得られませんでした。

より多くのユーザーにリーチするため、
[VS Code Goプラグイン](https://marketplace.visualstudio.com/items?itemName=golang.go)にテレメトリを有効にするかどうかを
ユーザーに尋ねる[プロンプト](https://go.dev/doc/telemetry#ide)を導入しました。

![The VS Code prompt](./gotelemetry/prompt.png)
*VS Codeによって表示されるテレメトリのプロンプト。*

この記事の執筆時点で、このプロンプトはVS Code Goユーザーの5%にロールアウトされており、テレメトリのサンプルは
週あたり約1800人の参加者にまで増えました。

![Weekly Uploads vs Prompt Rate](./gotelemetry/uploads.png)
*プロンプト表示はより多くのユーザーへのリーチに役立ちます。*

（最初の急増はおそらく
[VS Code Go nightly](https://marketplace.visualstudio.com/items?itemName=golang.go-nightly)拡張機能の
全ユーザーにプロンプトを表示したことによるものです。）

ただし、これによって直近の[Go調査結果](https://go.dev/blog/survey2024-h1-results)と比べてVS Codeユーザーへの
目立った偏りが生じています。

![Skew toward VS Code users](./gotelemetry/vscode_skew.png)
*テレメトリデータではVS Codeが過剰に代表されていると私たちは見ています。*

私たちは、言語サーバープロトコル自体の機能を使って、
[goplsを使用するLSP対応のすべてのエディタでプロンプトを表示する](https://go.dev/issue/67821)ことでこの偏りに
対処する予定です。

### テレメトリの成果

慎重を期して、テレメトリの最初のリリースでは、goplsで収集する指標はごく少数の基本的なものだけを提案しました。
その一つが[`gopls/bug`](https://go.dev/issue/62249)という
[スタックカウンター](https://go.dev/doc/telemetry#stack-counters)で、goplsが遭遇した予期しない、あるいは
「あり得ない」状態を記録するものです。実質的にはアサーションの一種ですが、プログラムを停止させる代わりに、
何らかの実行の中でそこに到達したことをスタックトレースとともにテレメトリに記録します。

[goplsのスケーラビリティ](https://go.dev/blog/gopls-scalability)に関する作業の中で、私たちはこの種のアサーションを
数多く追加していましたが、テストや自分たちの利用の中でそれらが失敗するのを目にすることはめったにありませんでした。
これらのアサーションのほとんどすべては到達不可能だろうと私たちは考えていました。

VS Codeでランダムなユーザーにテレメトリを有効にするよう促し始めたところ、これらの条件の多くが実際に到達されている
ことがわかり、スタックトレースの文脈は、長年存在していたバグを再現して修正するのに十分な場合がほとんどでした。
私たちはこうした問題を
[`gopls/telemetry-wins`](https://github.com/golang/go/issues?q=is%3Aissue+label%3Agopls%2Ftelemetry-wins)ラベルの
下で追跡し始め、テレメトリによってもたらされた「成果」を記録するようにしました。

私は「テレメトリの成果(telemetry wins)」という言葉に、もう一つの意味を見出すようになりました。テレメトリがある
場合とない場合のgopls開発を比較すると、文字通り _テレメトリが勝つ(telemetry wins)_ のです。

![Telemetry wins.](./gotelemetry/telemetry_wins.png)
*提案してくれたPaulに感謝します。*

テレメトリによって見つかったバグの中で最も驚かされたのは、その多くが _実際に存在するもの_ だったという点です。
もちろん、中にはユーザーからは見えないものもありましたが、かなりの数が実際にgoplsの誤った振る舞いでした。例えば、
相互参照の欠落や、特定の稀な条件下での微妙に不正確な補完などです。それらはまさに、ユーザーが多少苛立つかもしれない
ものの、わざわざイシューとして報告するほどではないと考えるような類のものでした。おそらくユーザーはその振る舞いが
意図されたものだと思い込んでいたことでしょう。もし報告したとしても、どう再現すればよいかわからなかったり、
スタックトレースを取得するためにイシュートラッカー上で長いやり取りが必要になったりしたかもしれません。テレメトリが
なければ、これらのバグの大半が発見され、ましてや修正されることは _現実的にあり得なかった_ でしょう。

そして、これらはすべてわずかな数のカウンターから得られたものです。私たちが計測していたのは _私たちが知っていた_
潜在的なバグのスタックトレースだけでした。では、私たちが予期していなかった問題についてはどうでしょうか。

### 自動化されたクラッシュレポート

Go 1.23には、ウォッチドッグプロセスを介した自動化されたクラッシュレポートの実装に利用できる新しい
[`runtime.SetCrashOutput`](https://go.dev/doc/go1.23#runtimedebugpkgruntimedebug) APIが含まれています。
[v0.15.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.15.0)から、goplsはクラッシュした際に
`crash/crash`スタックカウンターを報告するようになりました。ただし、それは _gopls自体がGo 1.23でビルドされている
場合に限られます_。

gopls@v0.15.0をリリースした時点では、Go 1.23の未リリースの開発版ビルドを使ってgoplsをビルドしていたユーザーは
私たちのサンプルの中でごくわずかでしたが、それでも新しい`crash/crash`カウンターは
[2件のバグ](https://github.com/golang/tools/releases/tag/gopls%2Fv0.15.2)を見つけました。

## Goツールチェインとその先にあるテレメトリ

わずかな量の計装と、私たちが目標としているサンプルのごく一部だけでテレメトリがこれほど有用であることを示せたので、
この先の見通しは明るいと言えます。

Go 1.23では、`go`コマンドやコンパイラ、リンカ、`go vet`といった他のツールを含め、Goツールチェイン内でテレメトリを
記録するようになりました。`vulncheck`とVS Code Goプラグインにもテレメトリを追加しましたし、
[`delve`にも追加することを提案しています](https://go.dev/issue/68384)。

もともとのテレメトリに関する一連のブログ記事では、テレメトリをGoの改善にどう活用できるかについて
[多くのアイデア](https://research.swtch.com/telemetry-uses)がブレインストーミングされていました。私たちは、
それらのアイデアやさらに多くのことを探求していくのを楽しみにしています。

goplsについては、信頼性の向上や、意思決定と優先順位付けの判断材料としてテレメトリを活用する計画です。Go 1.23で
有効になった自動化されたクラッシュレポートにより、プレリリースのテストでより多くのクラッシュを捕捉できると
期待しています。今後は、主要な操作のレイテンシや各種機能の利用頻度など、ユーザー体験を測定するためのカウンターを
さらに追加し、Go開発者にとって最も利益になる部分に力を注げるようにしていきます。

Goはこの11月で15歳になり、言語自体もそのエコシステムも成長を続けています。テレメトリは、Goのコントリビューターが
より速く、より安全に、正しい方向へ進んでいく上で重要な役割を果たすことになるでしょう。

By Robert Findley

