はじめに
こんにちは。CSIGの棚井です。
Go 1.23 Release Notes の内容を紹介する「フューチャー技術ブログ Go 1.23 リリース連載」の記事です。
Go toolchain に追加された Go Telemetry を取り上げます。
TL;DR
- Go 開発チームに「Go ツールチェーン(
go
,gopls
,govulncheck
)の利用状況、動作状況」をフィードバックするために追加されました - Go Telemetry のデフォルトは
local
mode のため、意図的にステータスを変更しない限りリモートアップロードは行われませんopt-in
により有効化した場合、自動アップロード後に telemetry.go.dev で集計結果が公開されます- ユーザ環境固有の情報は、Telemetry には含まれません
- 現時点(2024/07/25)ではアップロード数が少ない状況ですが、数が増えれば「世界的な Go の利用傾向、動作状況」が可視化できるようになります
telemetry in the Go toolchain #58409
Go の Telemetry の追加につながった Discussions(telemetry in the Go toolchain #58409)の内容を見ていきます。
2023年2月8日に Discussion が開かれた後、95 comments · 394 replies(506 comments との記載も)の会話を経て、telemetry は opt-in にするなどの仕様が固まり、Go1.23 でのリリースへとつながりました。
Discussions の冒頭には、投稿者により以下のような Telemetry の背景と、Go への導入提案が記載されています。
- ソフトウェア開発者たちが、自分らの作成したツールが「どのように利用されているのか?」や「期待通りに動作しているのか?」を自分たち自身にフィードバックする方法として、現代では「Telemetry(テレメトリ)」という方法がある。ソフトウェア内で収集した Telemetry をサーバに転送することで、開発者の疑問に答える方法である
- ツールを使うユーザの詳細な情報は集めずに、かつ、ツールの開発チーム側では効率的・効果的に作業を進められるような設計を目指して「Transparent Telemetry」というブログを投稿した
- Transparent Telemetry を Go のツールチェーンに加えることで、開発チームとユーザ両方の助けになる想定である。ただし、この計装の追加提案は Go のコマンドラインツール(
go
,gopls
,govulncheck
)を念頭に置いており、Go のコンパイラは含めていない
Go の開発言語自体をメンテナンスしている「Go 開発チーム」に向けた Telemetry の連携として、今回の Go Telemetry が追加されました。
Transparent Telemetry の日本語での説明記事としては、a2not さんの「Transparent Telemetryの概要」がとても参考になりました。
Why Telemetry? の Bug reports are not enough. に記載された話として、「Go1.14 から、macOS 環境で cgo を利用する net パッケージをコンパイルするには、 Xcode のインストールが求められるという バグ が3年近く放置されていた」というのは非常に衝撃的な内容でした。macOS を使っていることによる「そういうものなのかな」という誤解に、全世界の Go ユーザが気づけなかったようです。
今回の Go Telemetry の追加には、上記のような「ユーザ報告として上がってこないことにより、Go 開発チームが気づけていないバグ」をデータ駆動で検知しようとする試みが含まれているのではと、私は考えています。
環境構築
Go Telemetry を操作する環境を準備していきます。
go1.23rc2
の実行環境を準備します。
golang.org/dl で該当のバージョンを選択してインストールしてください。
$ go install golang.org/dl/go1.23rc2@latest |
go telemetry
としてコマンドが追加(参照実装箇所)されているので、go1.23rc2
でも Telemetry コマンドの呼び出しが可能です。
$ go1.23rc2 telemetry help |
help
で Telemetry の使い方を詳しく確認出来ました。コマンドの利用者が増えるにつれて、この情報量多めの説明文も徐々にそぎ落とされるのではと予想しています。
また、gotelemetry
としてのコマンドも用意されており、go install
で取得可能です。
$ go install golang.org/x/telemetry/cmd/gotelemetry@latest |
gopls
go telemetry
の各種コマンドは後程確認するとして、ここでは Go の Language Server である gopls
の Telemetry への対応状況を見ていきます。
Discussions(telemetry in the Go toolchain #58409)の中で gopls
に触れられていた、というのもあり、gopls
にはすでに Telemetry 機能が追加されています。
もし VSCode で Go の開発を行っている方であれば、Telemetry が有効な状態(※ ローカルへのファイル出力のみ有効。サーバへのアップロードは行わない)となっています。
gopls
, vscode-go
で Telemetry が追加されたバージョンと、対応するリリースノートを表に整理しました。
tool | version | release note |
---|---|---|
gopls | v0.14.0 | https://github.com/golang/tools/releases/tag/gopls%2Fv0.14.0 |
vscode-go | v0.40.0 | https://github.com/golang/vscode-go/releases/tag/v0.40.0 |
ログの出力場所を確認すると、local
, upload
のディレクトリが生成されていることが確認できます。
$ uname -s |
リリースノートをじっくりと確認する方であれば、VSCode, vscode-go の Telemetry の追記時点で、gopls
の Telemetry が始まったことに気づけたのかもしれません。
Go Telemetry を動かしてみる
Documentation > Go Telemetry の記載内容を参考に、Go Telemetry の各機能を見ていきます。
Telemetry mode
の設定
Go Telemetry には、3つの mode
が存在します。デフォルトは local
です。
各 mode
ごとに、ローカルに Telemetry が出力されるか、また、リモートサーバに Telemetry がアップロードされるかの挙動が異なります。
mode | ローカルに Telemetry が出力される | リモートサーバに Telelemetry がアップロードされる |
---|---|---|
local(default) | 〇 | ✕ |
on | 〇 | 〇 |
off | ✕ | ✕ |
mode
ステータスの確認と変更は、go telemetry
と gotelemetry
の両方で可能です。
go telemetry
の場合
$ go1.23rc2 telemetry |
gotelemetry
の場合
$ gotelemetry env |
また mode
の設定値は、次に取り上げる os.UserConfigDir()/go/telemetry
配下の mode というファイルに、更新日とセットで記録されています。
$ uname -s |
Telemetry の出力先
Telemetry は、ローカル環境の os.UserConfigDir()/go/telemetry
に出力されています。
os | 出力場所 |
---|---|
Linux | $XDG_CONFIG_HOME $HOME/.config |
macOS | $HOME/Library/Application Support |
Windows | %AppData% |
以降、本ブログでは、os.UserConfigDir()/go/telemetry
のパスを <gotelemetry>
と記載します。
Telemerty がローカルに出力され、リモートのサーバにアップロードされるまでの流れは以下のようになります(画像引用元)
Telemetry の内容
Telemetry には Basic counters と Stack counters の2種類があります。
gopls
の Telemetry を用いて、それぞれが <gotelemetry>
配下に出力しているログの内容を見ていきます。
Basic counters
ローカルの <gotelemetry>/local/local.2024-07-19.json
を開けてみたところ、以下のような中身となっていました。
※私の環境では \u003c
が出力されていたため、<
に手動で書き換えています。
{ |
$ cat local.2024-07-19.json | jq .Programs[].Program |
json ファイル内の項目から分かるように、gopls
と vscode-go/vscgo
のバージョン情報や動作環境、レイテンシーのカウントを記録しています。
例えば "gopls/client:vscode": 9
の場合は、VSCode によって gopls
のセッションが初期化された回数を表しています。Neovim や Eglot など他のエディタでも gopls
を利用している場合には、それぞれ別途 gopls/client:neovim
や gopls/client:eglot
の形式で記録されます。
gopls/client:vscode
の表記で表されている場合、gopls/client
をチャート名(chart name)、vscode
をバケット名(bucket name)と呼びます。
また、Basic counters では <10mx
, <50mx
の表記により、レイテンシのヒストグラムも記録しています。
"gopls/definition/error-latency:<10ms": 13, |
Stack counters
stack counter では、プログラムがクラッシュした回数のカウントと、クラッシュ時のコールスタックを記録しています。
以下、実際に gopls/bug
のスタックトレースが記録された Telemetry です。
{ |
stack counter により、滅多に起こらないエラーや再現の難しいエラーだとしても、適切なスタックトレースが Telemetry に記録されます。
Web のパフォーマンス最適化には「推測するな、計測せよ」という格言があり、まさにそれを Telemetry により実現しています。
Counter files
これまでに見てきた Telemetry のファイルは、json
フォーマットで記録される前に、以下のフォーマットで <gotelemetry>/local
に出力されています。
# スキーマ |
今回の動作検証環境では、以下のファイルが出力されていました。
# サンプルデータ |
- データスキーマとサンプルデータの対応
schema | example | reported by |
---|---|---|
program name | gopls | debug.BuildInfo |
program version | v0.16.1 | debug.BuildInfo |
go version | go1.22.3 | debug.BuildInfo |
GOOS | linux | runtime.GOOS |
GOARCH | amd64 | runtime.GOARCH |
date | 2024-07-22 | YYYY-MM-DD |
Reporting and uploading
おおよそ1週間に1回程度の頻度で、Telemetry でカウントしたデータが <gotelemetry>/local
配下に <date>.json
として出力されます。
出力されたデータは gotelemetry view
による可視化が可能です。
$ gotelemetry view |
gopls/client
gopls/references/latency
gopls/implementation/latency
ローカルに蓄積された全 Telemetry の集計と可視化になるため、本ブログ執筆時点の telemetry.go.dev よりは情報量の多いグラフが得られると思います。
また、<date>.json
の出力時に Telemetry の mode
が on
に設定されていた場合、リモートサーバへのファイルアップロードと、<gotelemetry>/upload
へのコピー作成が行われます。
Charts
Telemetry としてリモートに収集されたデータは、telemetry.go.dev に一般公開されています。
グラフ化された Chats と、その元となったデータは Reports として日付単位で公開されており、ブラウザで閲覧可能な状況となっています。
本ブログ執筆時点で Charts / 2024-07-20 を見てみると、68件のレポートを集計した結果との記載があります。
These charts were generated with data from 68 reports.
Discussions(telemetry in the Go toolchain #58409)には、分析に必要なレポート件数は約 16,000 件と記載されているため、今後のレポート件数の増加が重要になりそうです。
only about 16,000 reports are needed for 1% accuracy at a 99% confidence level.
現時点の少ないデータ数からでも、データ傾向は少しだけ見れます。
golang.org/x/tools/gopls, GoVersion
- Gopher の皆さんは、最新の go version を利用されている方が多い
gopls/client:{vscode,vscodium,vscode-insiders,code-server,eglot,govim,neovim,coc.nvim,sublimetext,other}
gopls
は VSCode での利用が多い
今後、レポートの母数が増えれば、世の中の Gopher 全体の傾向が、Telemetry により可視化できる未来が来るかもしれません。
ただし、現時点の Go Telemetry は opt-in により有効化する機能のため、データの偏り(データ母体が、あえて opt-in にするユーザの集まりになっている可能性がある点)には注意する必要があります。
おわりに
本ブログでは、Go1.23で追加された Go Telemetry を見てきました。
リポジトリの Issue 等を利用したユーザ報告駆動での調査とは別に、ツールに Telemetry を仕込んで「実挙動データを収集する」というトレンドについて、本ブログを執筆する中で改めて復習する機会となりました。以前に Terraform の実装コード読み を行った際に Open Telemetry の実装(terraform/telemetry.go)を見つけて、それ以降は「オブザーバビリティ・エンジニアリング」への関心を持ち続けていました。
最近の業務にて「ログ監視、インシデント対応」を担当する機会が増え、時期を合わせて Go のリリースノートに Telemetry が追加されたとの記載がありましたので、今回執筆させていただきました。
ここまで付き合いいただき、ありがとうございました。