Go Telemetry

目次

背景
概要
設定
カウンタ
レポートとアップロード
チャート
テレメトリ提案
IDEプロンプティング
よくある質問

背景

Goテレメトリは、Goツールチェーンプログラムがそのパフォーマンスと使用状況に関するデータを収集する方法です。「Goツールチェーン」とは、Goチームが維持管理する開発者ツールを意味し、goコマンドや、Go言語サーバーgoplsやGoセキュリティツールgovulncheckなどの補足ツールが含まれます。Goテレメトリは、Goチームと、Delveのような、彼らが選択した依存関係によって維持管理されるプログラムでの使用のみを目的としています。

デフォルトでは、テレメトリデータはローカルコンピュータのみに保持されますが、ユーザーは承認されたテレメトリデータのサブセットをtelemetry.go.devにアップロードすることをオプトインできます。アップロードされたデータは、使用状況と障害を理解するのに役立ち、GoチームがGo言語とそのツールを改善するのに役立ちます。

「テレメトリ」という言葉は、オープンソースソフトウェアの世界で、多くの場合当然のことながら、否定的な意味合いを持っています。しかし、ユーザーエクスペリエンスを測定することは、現代のソフトウェアエンジニアリングの重要な要素であり、GitHubの問題や年間調査などのデータソースは粗雑で遅れた指標であり、Goチームが答えられる必要があるタイプの質問には不十分です。Goテレメトリは、ツールチェーン内のプログラムが信頼性、パフォーマンス、使用状況に関する有用なデータを収集するのに役立つように設計されており、同時にユーザーがGoプロジェクトから期待する透明性とプライバシーを維持します。テレメトリの設計プロセスと動機について詳しくは、テレメトリのブログ記事をご覧ください。テレメトリとプライバシーについて詳しくは、テレメトリのプライバシーポリシーをご覧ください。

このページでは、Goテレメトリの仕組みを詳細に説明します。よくある質問への簡単な回答については、FAQを参照してください。

Go 1.23以降を使用し、Goチームへのテレメトリデータのアップロードをオプトインするには、次のコマンドを実行します。
go telemetry on
ローカルでの収集を含め、テレメトリを完全に無効にするには、次のコマンドを実行します。
go telemetry off
ローカルのみのテレメトリのデフォルトモードに戻すには、次のコマンドを実行します。
go telemetry local
Go 1.23より前は、golang.org/x/telemetry/cmd/gotelemetryコマンドでも実行できます。設定で詳細をご覧ください。

概要

Goテレメトリは、3つのコアデータ型を使用します

すべてのローカルGoテレメトリデータと設定は、ディレクトリos.UserConfigDir()/go/telemetryディレクトリに保存されます。以下では、このディレクトリを<gotelemetry>と呼びます。

下の図はこのデータフローを示しています。

このドキュメントの残りの部分では、この図のコンポーネントについて詳しく調べます。しかし、まず、それを制御する設定について詳しく見ていきましょう。

設定

Goテレメトリの動作は、単一の値であるテレメトリのモードによって制御されます。modeの可能な値はlocal(デフォルト)、on、またはoffです。

Go 1.23以降では、次のコマンドがテレメトリモードとやり取りします。

テレメトリ設定に関する情報は、読み取り専用のGo環境変数からも入手できます。

gotelemetryコマンドを使用して、テレメトリモードを設定したり、ローカルテレメトリデータを確認することもできます。このコマンドを使用してインストールします。

go install golang.org/x/telemetry/cmd/gotelemetry@latest

gotelemetryコマンドラインツールの完全な使用方法については、そのパッケージドキュメントを参照してください。

カウンタ

上記のように、Goテレメトリはカウンタを介して実装されています。カウンタには、基本カウンタとスタックカウンタの2つの種類があります。

基本カウンタ

基本カウンタは、カウントするイベントを記述する名前を持つインクリメンタルな値です。たとえば、gopls/client:vscodeカウンタは、VS Codeによってgoplsセッションが開始された回数を記録します。このカウンタと共に、gopls/client:neovimgopls/client:eglotなどが含まれ、異なるエディタや言語クライアントとのセッションを記録します。1週間を通して複数のエディタを使用した場合、次のカウンタデータが記録される可能性があります。

gopls/client:vscode 8
gopls/client:neovim 5
gopls/client:eglot  2

カウンタがこのように関連している場合、:の前にある部分をチャート名(この場合はgopls/client)、:の後の部分をバケット名vscode)と呼ぶことがあります。チャートについて説明する際に、これが重要な理由がわかります。

基本カウンタは、ヒストグラムを表すこともできます。たとえば、gopls/completion/latency:<50msカウンタは、自動補完が50ms未満で完了した回数を記録します。

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

これらのファイルは、実装されたプログラムの各実行インスタンスにメモリマップされます。メモリマップドファイルを使用することで、プログラムがすぐにクラッシュした場合でも、実装されたツールの複数のコピーが同時に実行されている場合でも、カウンタは安全に記録されます。

レポートとアップロード

約1週間ごとに、カウンタデータが集計されて、<date>.jsonという名前のレポートが<gotelemetry>/localディレクトリに作成されます。これらのレポートは、前の週のすべてのカウントを合計し、カウンタファイルに使用されたのと同じプログラム識別子(プログラム名、プログラムバージョン、Goバージョン、GOOS、GOARCH)でグループ化します。

ローカルレポートは、gotelemetry viewコマンドを使用してチャートとして表示できます。以下は、gopls/completion/latencyカウンターのサマリー例です。

アップロード

テレメトリのアップロードが有効になっている場合、毎週のレポート作成プロセスによって、アップロード設定に存在するカウンターのサブセットを含むレポートも生成されます。これらのカウンターは、次のセクションで説明されている公開レビュープロセスによって承認される必要があります。アップロードが成功すると、アップロードされたレポートのコピーが<gotelemetry>/uploadディレクトリに保存されます。

十分な数のユーザーがテレメトリデータのアップロードをオプトインすると、収集量を削減し、プライバシーを向上させながら統計的有意性を維持するために、アップロードプロセスはランダムに一部のレポートのアップロードをスキップします。

チャート

telemetry.go.devウェブサイトは、アップロードを受け入れるだけでなく、アップロードされたデータを公開しています。毎日、アップロードされたレポートは2つの出力に処理され、telemetry.go.devのホームページで公開されます。

チャートは、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://go.dokyumento.jp/issue/61038
issue: https://go.dokyumento.jp/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. 提案者は、chartconfigパッケージのconfig.txtを変更するCLを作成し、そこに目的の新しいカウンター集計を含めます。
  2. 提案者は、このCLをマージするための提案を提出します。
  3. 問題に関する議論が解決したら、Goチームのメンバーが提案を承認または拒否します。
  4. 自動プロセスによってアップロード設定が再生成され、新しいチャートに必要なカウンターのアップロードが可能になります。このプロセスは、関連するプログラムの新しいバージョンがリリースされるたびに、アップロード設定に定期的に追加します。

承認されるためには、新しいチャートは機密のユーザー情報を持ち運ぶことができず、さらに有用で実現可能である必要があります。有用であるためには、チャートは特定の目的を果たし、実行可能な結果をもたらす必要があります。実現可能であるためには、必要なデータを確実に収集することができ、結果の測定値が統計的に有意である必要があります。実現可能性を示すために、提案者は、ターゲットプログラムにカウンターを組み込み、最初にローカルで収集するように求められる場合があります。

このような提案の完全なセットは、GitHubの提案プロジェクトで確認できます。

IDEプロンプティング

テレメトリが私たちが尋ねたい種類の質問に答えるためには、アップロードをオプトインするユーザーの数は多くなくても構いません。約16,000人の参加者であれば、必要な粒度で統計的に有意な測定が可能になります。しかし、この健全なサンプルを収集するには依然としてコストがかかります。多くのGo開発者にオプトインを尋ねる必要があるからです。

さらに、(おそらくGoブログ記事を読んだ後)多くのユーザーがオプトインを選択した場合でも、それらのユーザーは経験豊富なGo開発者に偏っている可能性があり、時間の経過とともにその初期サンプルはさらに偏っていきます。また、人がコンピューターを交換するときは、再び積極的にオプトインを選択する必要があります。テレメトリのブログ投稿シリーズでは、これはオプトインモデルの「キャンペーンコスト」と呼ばれています。

参加ユーザーのサンプルを新鮮に保つために、Go言語サーバーgoplsは、ユーザーにGoテレメトリへのオプトインを促すプロンプトをサポートしています。VS Codeからの表示例を以下に示します。

ユーザーが「はい」を選択した場合、モードgotelemetry onを実行した場合と同様にonに設定されます。このようにして、オプトインをできるだけ簡単にし、常にGo開発者の大規模かつ多層的なサンプルに到達することができます。

よくある質問

Q: Goテレメトリを有効または無効にするにはどうすればよいですか?

A: go install golang.org/x/telemetry/cmd/gotelemetry@latestでインストールできるgotelemetryコマンドを使用します。gotelemetry offを実行してすべてを無効にします(ローカル収集も含む)。gotelemetry onを実行して、承認済みのカウンターをtelemetry.go.devにアップロードするなど、すべてを有効にします。設定セクションで詳細を確認してください。

Q: ローカルデータはどこに保存されますか?

A: os.UserConfigDir()/go/telemetryディレクトリです。

Q: オプトインした場合、データはどのくらいの頻度でアップロードされますか?

A: 約週1回です。

Q: オプトインした場合、どのようなデータがアップロードされますか?

A: アップロード設定にリストされているカウンターのみがアップロードされます。これは[チャート設定]から生成され、より読みやすいかもしれません。

Q: カウンターをアップロード設定に追加するにはどうすればよいですか?

A: 公開提案プロセスを通じて行います。

Q: アップロードされたテレメトリデータはどこで見ることができますか?

A: アップロードされたデータは、telemetry.go.devでチャートまたはマージされたサマリーとして公開されています。

Q: Goテレメトリのソースコードはどこにありますか?

A: golang.org/x/telemetryにあります。