ElasticsearchとElastic APMでアプリを監視する

APM(アプリケーションパフォーマンス監視)とは?

APMについて説明する場合、ログやインフラメトリックの"監視性"など、別の側面も考えるとよりわかりやすくなります。ログとAPM、インフラメトリックは監視の3大要素です。

3つの領域には重なり合う部分もあり、相互に関連付ける際に役立ちます。ログは、エラーが生じた痕跡を示すかもしれませんが、エラーの理由までは示しません。メトリックはサーバー上でCPU使用量にスパイクがあったことを示すかもしれませんが、何が原因だったかは示しません。しかし、うまく組み合わせて活用すれば、はるかに広い範囲の問題を解決できる可能性があります。

ログ

はじめにいくつかの定義について考えておきましょう。ログとメトリックには、わずかな違いがあります。通常、ログは何かが生じたときに発信されるイベントです。あるリクエストが受信されたとか、反応があったとか、ファイルを開いた、コードでprintfが生じた... といった出来事です。

たとえば、Apache HTTPサーバーのプロジェクトからくるよくあるログ形式はこんな感じです(フェイクデータ、短縮のため一部省略)。

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "GET /ESProductDetailView HTTP/1.1" 200 6291
264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "POST /intro.m4v HTTP/1.1" 404 7352
264.242.88.10 - - [22/Jan/2018:16:38:53 -0800] "POST /checkout/addresses/ HTTP/1.1" 500 5253

ログの情報は、アプリケーションの全体を把握するというより、コンポーネントレベルにとどまる傾向にあります。しかし人間が読む上では便利です。上の例では、IPアドレスと、明らかに設定のないフィールド、日付、ユーザーがアクセスしていたページ(とその方法)、いくつかの数字を確認することができます。私の経験から、一連の数字がレスポンスコード(200はよい、404は良くないが、500よりはマシ)であることと、データが返された量であることがわかります。

ログは通常、対応するアプリケーションやサービスが実行されているホスト/マシン/コンテナーインスタンス上で使用でき、この例のように人間が読める情報であるため、"便利"です。一方でログには、「コードを書いておかなければ、プリントされない」という本質的なデメリットもあります。Rubyでputsを使うか、Javaでsystem.out.printlnするか、あるいは類似の作業が必須です。またプリントする場合も、フォーマットが重要です。前出のApacheログに、見慣れない日付フォーマットが含まれています。たとえば"01/02/2019"という日付を考えてみましょう。米国に住む私にとっては2019年1月2日という意味ですが、世界の多くの仲間はこの日付を2019年2月1日と読みます。ロギングでstatementの形式を決定する際は、こうした点も考慮されることをお勧めします。

メトリック

一方、メトリックは周期的なサマリーやカウントの情報が主です。たとえばこの10秒間に、平均CPUは12%で、アプリケーションが使用したメモリ量は27MB、であるとか、プライマリディスクの容量は71%、といったことです(いま筆者のマシンのメトリックを確認してみました)。

上のスクリーンショットは、あるMacで実行されているiostatです。多くのメトリックがあることがわかります。メトリックは傾向や履歴を示したいときに便利であり、シンプルで予測可能、また信頼できるルールを作成してインシデントや異常を捉える場合に特に役立ちます。メトリックのデメリットとして、インフラレイヤーの監視や、コンポーネントインスタンスレベル(ホスト、コンテナー、ネットワークなど)のデータ捕捉が中心で、カスタムアプリケーションレベルのデータをあまり扱わない点があります。というのも、メトリックは一定の経過時間に対してサンプルされるため、わずかな外れ値が"平均化"されるリスクを伴うためです。

APM

メトリックとログのギャップに橋を架ける存在がアプリケーションパフォーマンス監視です。ログやメトリックは、インフラや複数のコンポーネントを扱う横断的なデータです。APMは特にアプリケーションに注目し、エンドユーザーエクスペリエンスを含むスタック中のアプリ層を、IT部門や開発者が監視できるようサポートします。

監視にAPMを追加するメリットとして、次のような点があります。

  • サービス提供にかかる時間と、クラッシュの原因を把握できる
  • サービスと他の要素の通信状況や、ボトルネックを可視化できる
  • パフォーマンスのボトルネックやエラーの予防的な発見・修正に役立つ
    • 最良のシナリオは、多数のエンドユーザーが影響を受ける前の発見・修正
  • 開発チームの生産性向上をサポート
  • ブラウザー上でエンドユーザーエクスペリエンスを追跡可能

特に注目したいのが、"APMにはコードが通じる"という点です(この後詳しく取り上げます)。

ログとAPMで、得られる情報を比較してみましょう。先ほどこのようなログエントリがありました:

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "GET /ESProductDetailView HTTP/1.1" 200 6291

先ほど見た通り、よい内容になっています。レスポンスに成功しており(200)、6,291バイトを返しました。しかし、レスポンスに16.6秒かかったことは示されていません。これは次のAPMスクリーンショットに表示されています。

その他にも豊富なコンテクストが見て取れます。最初のログには、このようなエラーもありました:

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "POST /checkout/addresses/ HTTP/1.1" 500 5253

APMが捉えた内容はこうなります:

最終発生日時、発生頻度、アプリケーションで処理されたか否か、という情報が表示されています。たとえばNumberParseExceptionを使って例外処理の詳細を見ると、エラーが発生した回数の分布がウインドウで視覚的に表示されます。

パッと見て、一定の時間に数回起きているということ、一日中発生していることがわかります。ログで見ても、ログファイルの1つに対応するスタックの痕跡が見つかるはずです。しかしAPMのように、そのコンテクストやメタデータまで見つかる可能性は高くありません。

赤い長方形の部分はこの例外処理を実施したコード行を示し、APMが提供するメタデータが問題の正確な内容を伝えています。pythonプログラマーでない筆者のような人間が見てもどういう問題であるか正確に理解でき、チケットをオープンするために必要十分な情報があります。

スクリーンショットで見るAPMオプションツアー

Elastic APMについて一日中語ることもできる筆者ですが(よかったらTwitterで検索してください)、ここではスクリーンショットを使って、もう少し視覚的にご紹介したいと思います。早速ツアーをはじめましょう。

APMを開く

KibanaでAPMアプリケーションを開くと、Elastic APMに搭載されているすべてのサービスが表示されます:

サービスの詳細を見る

個々のサービスについて詳細を見ることができます。今回は"petclinic-spring"サービスを見てみましょう。各サービスとも、レイアウトは似ています:

左上にレスポンスタイムがあります。平均、95パーセンタイル、99パーセンタイルがあり、外れ値の部分を表示しています。さまざまな線グラフのエレメントを表示/非表示にして、外れ値がチャート全体に与える影響をわかりやすくすることもできます。右上はレスポンスコードです。時間に対してRPM(requests per minute/1分あたりリクエスト数)を詳しく表示しています。実際の画面では、各チャートの上でマウスを動かすとポップアップが現れ、特定の時間のサマリーを表示します。最初に得られるインサイトは、データを深堀りせずともすぐにわかります。すなわち、レイテンシの大きなスパイクに、"500"のレスポンス(サーバーエラー)がまったくありません。

トランザクションレスポンスタイムを詳しく見る

引き続きトランザクションサマリーを見ると、下の方にリクエストの詳細があります。各リクエストは、基本的には(さまざまなエージェントAPIを使用して初期設定を拡張可能できる)アプリケーション中の異なるエンドポイントです。リクエストは列見出しで並べ替えできますが、筆者が個人的に好んで使うのは"impact"列です。これは、そのリクエストのレイテンシと出現度を考慮します。今回の事例では、"getOwners"が最も問題を生じさせているように見えますが、それでも平均レイテンシは96ミリ秒に留まっています。このトランザクションを詳細にドロップダウンしていくと、先ほどと同じレイアウトが表示されます。

"ウォーターフォール作戦"

さて、最も遅いリクエストでも、1秒未満にレスポンスしていることがわかりました。下に向かってスクロールしてゆくと、トランザクション中のオペレーションが滝のように表示されています。

クエリ詳細表示

見ると確かに、大量のSELECT文があります。APMでは実行された実際のクエリを表示させることができます。

分散トレーシング

このアプリケーションスタックは、多層化されたマイクロサービスアーキテクチャーを扱っています。すべての層にElastic APMを組み込んであるため、[View full trace]ボタンを押してこのコールに関与する全要素が入るまでズームアウトすることが可能です。こうして、トランザクションに参加したすべてのコンポーネントの分散トレーシングを表示します:

多層的にトレーシングする

今回の事例で最初に見たのは、他の層がコールする"Spring"という層でした。いまこの画面で、"petclinic-node"が"petclinic-spring"層をコールしたことがわかります。これは2つの層でしたが、ブラウザー(React)層からはじまるより多層的な例もあります。

リアルユーザー監視

分散トレーシングの力を最大に引き出すためには、リアルユーザー監視(RUM)も含めて、できる限り多くのコンポーネントやサービスを組み込むことが重要です。サービスレスポンスタイムの早さが、必ずしもブラウザーでのすばやい動作を意味するわけではありません。つまり、ブラウザー上でのエンドユーザーエクスペリエンスを測定することこそが重要です。この事例で、分散トレーシングは4つの異なるサービスが同時に実行されていることを示しています。複数あるサービスの1つが、Webブラウザー(クライアント)です。53ミリ秒の時点でdomはインタラクティブでした。67ミリ秒では、domが完了していることがわかります。

UIにとどまらない魅力

Elastic APMは使いやすいAPM UIに加え、アプリ開発者に必要な機能を豊富にそろえています。そして、追跡データをUIで表示できるだけでなく、一歩深く活用できます。実は、Elastic APMデータは1つのインデックスとなっています。ログやメトリックから、事業データまでの情報が揃うことにより、サーバー遅延が収益に及ぼした影響を把握することも、影響の大きいリクエストを調べるなどして、次のコード拡張の計画策定にAPMデータを役立てることも可能です。

APMはデフォルトの可視化とダッシュボード機能を搭載しており、ログとメトリック、さらに事業データを組み合わせて可視化することができます。

Elastic APMを使いはじめる

Elastic APMは、LogstashやBeatsと似たデプロイトポロジーを使い、組み合わせて実行することができます:

APMサーバーはデータプロセッサーとして振る舞い、APMデータをAPMエージェントからElasticsearchに転送します。インストール手順もシンプルです。ドキュメントの"install and run"ページを参照いただくか、Kibanaで"K"ロゴをクリックしてホーム画面を表示し、"Add APM"オプションをクリックしてはじめることができます:

画面の案内にしたがって進むだけで、APMサーバーを稼働させることができます:

設定が完了したら、搭載させる各エージェントタイプについてKibanaのチュートリアルを参照することができます:

わずか数行のコードで、すべての設定が完了します。

Elastic APMの入口

新しいことを学ぶには、実際に手を動かしてみるのが一番です。また、その方法も1つではありません。実際のインターフェースをライブで、リアルに見てみたいという方はこちらのAPMデモ環境をクリックしてご覧ください。ローカルで実行してみたいという方は、APMサーバーダウンロードページの手順に沿って進めていただくことができます。

最も手軽な方法は、Elastic CloudElasticsearch Serviceです。APMサーバー6.6、Kibanaインスタンス、機械学習ノードを含むすべてのElasticsearchデプロイが、SaaSで提供されており、1分ほどで使いはじめることができます(全サービスを2週間の無料トライアルでお試しいただけます)。クラウドサービスのため、デプロイインフラの保守/管理を行わなくて済むという大きなメリットがあります。

Elasticsearch ServiceでAPMを有効化する

APMクラスターを作成する(または既存のクラスターにAPMを追加する)には、クラスター設定の画面でAPM設定のセクションが表示されるまで下にスクロールします。既存のデプロイをアップデートする場合は[Enable]、[Save changes]の順にクリック、新規デプロイの場合は[Create deployment]をクリックします。

ライセンス

ElasticのAPMサーバーと、全APMエージェントはオープンソースとして提供されています。洗練されたAPM UIはElastic Stackでデフォルトの配布、また無料のベーシックライセンスより使用可能です。アラートや機械学習と統合する場合はベースとなるオプションのライセンスが必要になり、アラートにはゴールド、機械学習にはプラチナをご購入いただく必要があります。

まとめ

APMは、アプリケーションのあらゆる層で起きていることを表示します。機械学習やアラートと統合できるElastic APMなら検索機能を最大に活用でき、アプリケーションインフラの可視性が大きく向上します。トランザクションから痕跡、エラー、例外処理まで可視化でき、洗練されたAPMユーザーインターフェースがコンテクストも表示します。問題が発生していないときも、Elastic APMのデータを参考に修正内容の優先順位付けを行って、アプリケーションパフォーマンスの最大化と、ボトルネックの排除に取り組むことができます。

Elastic APMと監視に関するウェビナーも複数あります。併せてぜひご覧ください。

はじめてみませんか? APMに関するトピックはディスカッションフォーラムでもご覧いただけます。チケットの送信や機能のリクエストは、APM GitHub reposにお寄せください。