Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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) を設定します。handlernil の場合、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))
//  }()

このスニペットは以下のことを明確に指示しています。

  1. 前提条件: アプリケーションがまだHTTPサーバーを実行していない場合。
  2. 必要なインポート: net/httplog パッケージのインポート。
  3. コードの場所: main 関数内に追加すること。
  4. サーバー起動ロジック:
    • 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/httplog パッケージ。
  • コードの配置場所: 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言語の net/http/pprof パッケージのドキュメント
  • Go言語の net/http パッケージのドキュメント
  • Go言語のプロファイリングに関する一般的な知識
  • go tool pprof の使用方法に関する情報