[インデックス 13743] ファイルの概要
このコミットは、Go言語の標準ライブラリである net/http/pprof
パッケージのドキュメントを更新するものです。具体的には、src/pkg/net/http/pprof/pprof.go
ファイル内のgodocコメントが変更されています。
コミット
net/http/pprof
パッケージのドキュメントが更新され、HTTPサーバーを起動するための具体的な手順が追加されました。これにより、go tool pprof
コマンドを使用する際に、アプリケーションがHTTPサーバーを既に実行している必要がないという問題が解決されます。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f4c22b29d498c2e942a15cc8b3d2ef30b6bab1e0
元コミット内容
net/http/pprof: updated documentation (run an http server)
Added instructions for starting an http server
to the godoc header for this package. With the old
instructions, the example "go tool pprof..." commands
wouldn't work unless you happen to be running an http
server on port 6060 in your application.
R=golang-dev, minux.ma, adg, giacomo.tartari
CC=golang-dev
https://golang.org/cl/6483049
変更の背景
この変更の背景には、Go言語のプロファイリングツールである go tool pprof
の利用に関する既存のドキュメントの不備がありました。以前のドキュメントでは、net/http/pprof
パッケージをインポートするだけでプロファイリングが可能であるかのように示されていましたが、実際には go tool pprof
がプロファイルデータを取得するためには、アプリケーションがHTTPサーバーを起動し、特定のパス (/debug/pprof/
) でプロファイル情報を公開している必要がありました。
コミットメッセージにあるように、「古い指示では、アプリケーションがポート6060でHTTPサーバーを実行していない限り、例示されている go tool pprof...
コマンドは機能しませんでした。」この問題に対処するため、ユーザーがプロファイリングを試みる際に、HTTPサーバーを明示的に起動する方法をドキュメントに追加する必要がありました。これにより、go tool pprof
の利用がより直感的で、エラーなく行えるようになります。
前提知識の解説
Go言語のプロファイリング (pprof
)
Go言語には、プログラムのパフォーマンスを分析するための強力なプロファイリングツールが組み込まれています。これは主に runtime/pprof
パッケージと net/http/pprof
パッケージによって提供されます。
runtime/pprof
: プログラム内で直接プロファイルデータを生成し、ファイルに書き出すためのAPIを提供します。CPUプロファイル、ヒーププロファイル、ゴルーチンプロファイルなどを手動で取得する際に使用されます。net/http/pprof
:runtime/pprof
の機能をHTTPエンドポイントとして公開するためのパッケージです。このパッケージをインポートすると、デフォルトのHTTPサーバー (http.DefaultServeMux
) に/debug/pprof/
以下のパスが登録され、Webブラウザやgo tool pprof
からプロファイルデータにアクセスできるようになります。
go tool pprof
go tool pprof
は、Go言語のプロファイルデータを解析し、視覚化するためのコマンドラインツールです。CPU使用率、メモリ割り当て、ブロックされたゴルーチンなどの情報を、テキスト形式、グラフ形式(Graphvizが必要)、Webインターフェースなどで表示できます。
go tool pprof http://localhost:6060/debug/pprof/heap
のように、HTTPエンドポイントを指定してプロファイルデータを取得するのが一般的な使用方法の一つです。この場合、go tool pprof
は指定されたURLからプロファイルデータをダウンロードし、解析します。
HTTPサーバー (net/http
)
Go言語の標準ライブラリには、HTTPクライアントとサーバーを構築するための net/http
パッケージが含まれています。
http.ListenAndServe(addr string, handler http.Handler)
: 指定されたアドレス (addr
) でHTTPサーバーを起動し、リクエストを処理するためのハンドラ (handler
) を設定します。handler
がnil
の場合、http.DefaultServeMux
が使用されます。net/http/pprof
パッケージは、このhttp.DefaultServeMux
にプロファイル用のハンドラを登録します。log.Println(...)
: Go言語の標準ロギングパッケージlog
の関数で、メッセージを標準出力または指定された出力先に書き出します。サーバーがエラーで終了した場合にその情報をログに出力するために使用されます。go func() { ... }()
: Go言語のゴルーチンを起動するための構文です。go
キーワードの後に無名関数を記述し、即座に実行することで、その関数を新しいゴルーチンとして並行して実行します。HTTPサーバーは通常、メインの処理をブロックしないようにゴルーチン内で起動されます。
技術的詳細
このコミットの技術的な詳細は、net/http/pprof
パッケージのgodocコメントに、HTTPサーバーを起動するための具体的なGoコードスニペットを追加した点に集約されます。
以前のドキュメントでは、ユーザーは単に import _ "net/http/pprof"
を追加するだけでプロファイリングが可能になると誤解する可能性がありました。しかし、net/http/pprof
はプロファイルデータをHTTP経由で公開する機能を提供するだけであり、実際にHTTPリクエストを受け付けるためには、アプリケーション自身がHTTPサーバーを起動している必要があります。
追加されたコードスニペットは、この不足している部分を補完します。
// If your application is not already running an http server, you
// need to start one. Add "net/http" and "log" to your imports and
// the following code to your main function:
//
// go func() {
// log.Println(http.ListenAndServe("localhost:6060", nil))
// }()
このスニペットは以下のことを明確に指示しています。
- 前提条件: アプリケーションがまだHTTPサーバーを実行していない場合。
- 必要なインポート:
net/http
とlog
パッケージのインポート。 - コードの場所:
main
関数内に追加すること。 - サーバー起動ロジック:
go func() { ... }()
: HTTPサーバーの起動をメインのゴルーチンから分離し、バックグラウンドで実行します。これにより、サーバーがリクエストを待ち受けている間も、main
関数内の他の処理が続行できます。http.ListenAndServe("localhost:6060", nil)
:localhost:6060
でHTTPサーバーを起動します。nil
をハンドラとして渡すことで、http.DefaultServeMux
が使用されます。net/http/pprof
はこのデフォルトのマルチプレクサにプロファイル用のハンドラを登録するため、この設定で正しく機能します。log.Println(...)
:ListenAndServe
はエラーが発生した場合にエラーを返します。このエラーをログに出力することで、サーバーが予期せず停止した場合にデバッグ情報を提供します。
この変更により、net/http/pprof
を利用しようとする開発者は、プロファイリングを機能させるために必要なHTTPサーバーの起動手順を明確に理解できるようになりました。これは、Go言語のプロファイリング機能の使いやすさを大幅に向上させるものです。
コアとなるコードの変更箇所
--- a/src/pkg/net/http/pprof/pprof.go
+++ b/src/pkg/net/http/pprof/pprof.go
@@ -14,6 +14,14 @@
// To use pprof, link this package into your program:
// import _ "net/http/pprof"
//
+// If your application is not already running an http server, you
+// need to start one. Add "net/http" and "log" to your imports and
+// the following code to your main function:
+//
+// go func() {
+// log.Println(http.ListenAndServe("localhost:6060", nil))
+// }()
+//
// Then use the pprof tool to look at the heap profile:
//
// go tool pprof http://localhost:6060/debug/pprof/heap
コアとなるコードの解説
変更は src/pkg/net/http/pprof/pprof.go
ファイルのgodocコメント内で行われています。具体的には、import _ "net/http/pprof"
の説明の直後に、HTTPサーバーを起動するための新しい指示が追加されました。
追加されたコメントブロックは、以下の重要な情報を提供します。
- 条件: アプリケーションがまだHTTPサーバーを実行していない場合。
- 必要なインポート:
net/http
とlog
パッケージ。 - コードの配置場所:
main
関数内。 - 具体的なコードスニペット:
このスニペットは、go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }()
localhost:6060
でHTTPサーバーを新しいゴルーチンとして起動します。これにより、net/http/pprof
が提供するプロファイリングエンドポイントが利用可能になり、go tool pprof
コマンドが正しく機能するようになります。log.Println
は、ListenAndServe
が返す可能性のあるエラーを捕捉し、ログに出力するために使用されます。
この追加により、net/http/pprof
パッケージの利用者は、プロファイリングを行うために必要な環境設定(特にHTTPサーバーの起動)について、より明確なガイダンスを得られるようになりました。
関連リンク
- Go CL 6483049: https://golang.org/cl/6483049
参考にした情報源リンク
- Go言語の
net/http/pprof
パッケージのドキュメント - Go言語の
net/http
パッケージのドキュメント - Go言語のプロファイリングに関する一般的な知識
go tool pprof
の使用方法に関する情報