Go 1.23以降のテレメトリ

Telemetry in Go 1.23 and beyond by Robert Findley

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テレメトリの最初の実装は、2023年10月、Go言語サーバー goplsv0.14でリリースされました。リリース後、 リリースノートやGophers Slackチャンネルでの議論に触発されたのか、 およそ100人のユーザーがアップロードを有効にし、データが少しずつ集まり始めました。そして間もなく、テレメトリは goplsの最初のバグを見つけました。

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

IDEでのプロンプト表示

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

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

より多くのユーザーにリーチするため、 VS Code Goプラグインにテレメトリを有効にするかどうかを ユーザーに尋ねるプロンプトを導入しました。

The VS Code prompt VS Codeによって表示されるテレメトリのプロンプト。

この記事の執筆時点で、このプロンプトはVS Code Goユーザーの5%にロールアウトされており、テレメトリのサンプルは 週あたり約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のスケーラビリティに関する作業の中で、私たちはこの種のアサーションを 数多く追加していましたが、テストや自分たちの利用の中でそれらが失敗するのを目にすることはめったにありませんでした。 これらのアサーションのほとんどすべては到達不可能だろうと私たちは考えていました。

VS Codeでランダムなユーザーにテレメトリを有効にするよう促し始めたところ、これらの条件の多くが実際に到達されている ことがわかり、スタックトレースの文脈は、長年存在していたバグを再現して修正するのに十分な場合がほとんどでした。 私たちはこうした問題を gopls/telemetry-winsラベルの 下で追跡し始め、テレメトリによってもたらされた「成果」を記録するようにしました。

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

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カウンターは 2件のバグを見つけました。

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

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

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

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

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

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

By Robert Findley