AutoInstuments: Rubyのカスタムコードパフォーマンスを手間なくモニタリング

BY Derek Haynes

October 30, 2019

Webアプリケーションで、カスタムコード(requireしたライブラリではなく、自分で書いたコード)をモニタリングすることは、長い間私の悩みでした。確かに、custom instrumentation API はありますが、custom instrumentationのコードを追加するのが楽しい人はいるでしょうか?いませんよね。 

もしあなたのアプリケーションが、Scoutがデフォルトでモニタリングする一般的なライブラリでほとんどの時間を使われている場合は、このカスタムコードモニタリングは、そんなに大きな問題ではありません。しかし、下記のようなトレースの場合は話が違います。

custom_code_trace_wo_auto.png

これらのようなトレースは、私たちが欲している以上によくあります。一般的なwebリクエストで、カスタムコードがデータベースの次に時間を使っていることを発見しました。

% Time Consumed By Category across ap...

これ程多くの時間を使っているカスタムコードなのに、どうしてScout(他のAPMベンダー)は、カスタムコードのパフォーマンスについてもっと簡単な可視化した情報を提供することができないのでしょうか?ほとんどのAPMエージェントは、モニタリングするために似たようは手段を使っています。私たちは、よく使われるライブラリのメソッドをScoutのモニタリングコードで囲むことで、モニタリングを行なっています。カスタムコードに関しては、私たちの方で事前に知ることができないため、私たちのモニタリングコードで囲むことができません。また、全てのメソッドをモニタリングすることも、オーバーヘッドが大きくなりすぎるためにできません。

Rails profilingとScoutProfの上位互換

私たちは、困難な問題だからといって、このカスタムコードモニタリングも問題を無視してきたわけではありません。事実、初期の頃からこの問題を解決するための実験を行なってきました。その一つが、ScoutProfです。BETA版としてリリースしましたが、下記三つの理由からGA版となることはありませんでした。

  1. ScoutProfはカスタムコードをサンプリングするが、結果が安定しない場合があった
  2. Scoutのモニタリング方法が決定的なのに対し、ScoutProfはサンプリングのため、それらの結果一緒にを表示するのが難しいことがあった
  3. インストールしたアプリに予期しない邪魔をすることが、時たまあった

これらの問題のために、私たちはScoutProfを一般公開(またはサンプリングについて再調査)することに至りませんでした。2018年後半、Scoutのエンジニア Dave Andersonが思いついた案が、RuboCopがコードを分析、フォーマットするのと同じようにカスタムコードをモニタリングするコードを組み込んだらどうかというものであった。AutoInstrumentsは、コード読み込み時に、RubyのAbstract Syntax Tree(AST)を調べることで、Ruby on Rails コントローラー内ののカスタムコードをScoutのモニタリングコードで囲んでいます。他のScoutがデフォルトでモニタリングするライブラリ同様に、これらのカスタムコードがトレースに表示されます。オーバーヘッドが大きくなりすぎないように、コントローラーにAutoInstrumentsの範囲を絞っています。

AutoInstrumentsとNewRelicのCustom instrumentationの比較

AutoInstrumentsは、2019年9月上旬に、Samuel Williams の協力もありBETA版としてリリースされました。その結果に、私はとても満足しています。下の画像は、ScoutのRailsアプリケーションの同じコントローラーアクションのトレースになります。左がNewRelic(AutoInstumentation機能はありません。)、右がScoutになっています。

newrelic_scout.png

New Relicでは、67.5%がコントローラーとして表示されているのに対して、Scoutでは1%となっています。つまり、その他の部分はAutoInsturmentsによってモニタリングをされているということです。

Scoutは、AutoInstrumentsによって、61%の時間がカスタムメソッド、TransactionTrace::GroupCollection.new(@span_trace)に使われていることを特定しています。その上、AutoInstrumentによって計測されたコードは、Backtraceが一緒に取得され、Githubと統合することによって、実際のコードを表示することが可能になります。

auto_backtrace.png

今回は、一つのトレースのみの例ですが、これがアプリケーション全体で有効にされたら王なるでしょうか?AutoInstrumentsを利用することによって、計測されていなかったいなかったカスタムコードの量が、5倍近く少なくなったことを発見しました。

Time Allocated to Uninstrumented Code...

AutoInstrumentsの使用方法

AutoInstrumentsの利用方法に関しては、こちらのアップグレードドキュメントに従ってください。また、AutoInstrumentsについてのよくある質問(実装に関して、オーバーヘッドなど)もこちらにまとめられらていますので、参考にしてください。

質問などございましたら、いつでもsupport@scoutapm.comまでご連絡ください。