その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

pprof を使って nodejs アプリケーションのプロファイルを取る

pprof って go のやつでしょ? node のプロファイルが取れるわけ無いやろ,と僕も思っていたんですが以下のライブラリを使うことで取れることがわかりました.

github.com

使い方については Using the Profiler に書いてあるとおりで,アプリケーション側に

const profile = await pprof.time.profile({
  durationMillis: 10000,    // time in milliseconds for which to 
                            // collect profile.
});
const buf = await pprof.encode(profile);
fs.writeFile('wall.pb.gz', buf, (err) => {
  if (err) throw err;
});

という風に書いてあげるとwall time (所要時間) ベースのプロファイルを取ることができます *1.また,その下の Collect a Heap Profile に書いてある手順に従うと heap のプロファイルをとることもできます.


というわけで Express を使ったアプリケーションのプロファイルを pprof で取得するサンプルプロジェクトを作成しました.

github.com

これを試しに実行してみると,以下のようなプロファイル結果を得ることが可能です.

f:id:moznion:20201005120750p:plain

見慣れた pprof の UI ですね.

f:id:moznion:20201005120815p:plain

Flame Graph も取れて非常に便利.これ普通にガチで便利に使えます.




最初は pprof を node に使うとかめっちゃ hacky だな〜と思っていたのですが,確かに go ではないプロジェクトであっても "pprof" というプロファイリングフォーマットに乗っておくと,プロファイルの解析や UI のエコシステムに乗れるから便利なんだな〜という気づきを得ました.共通フォーマットを活用することでレバレッジを効かせていくのは重要ですね.

*1:ところで "Requiring from the command line" に書いてある手順に従ってもうまくプロファイルが取れなかったのですが,これどうやるのが正解なんですかね……?