この記事は Cristian González – OpenCensus チーム – 2019 年夏季 Google ソフトウェア エンジニアリング インターン、コロンビア国立大学コンピュータおよびシステム エンジニアリング学部生による Google Open Source Blog の記事 "OpenCensus Web: Unlocking Full End-to-End Observability for Your Entire Stack" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
OpenCensus Web は、ユーザーがウェブページのパフォーマンスをどのように感じているかをトレースし、監視するツールです。診断方法がわからないパフォーマンスの問題がウェブページで発生していないかどうかを判断する際に役立ちます。
ウェブ アプリケーションの所有者は、実際のユーザーが感じるパフォーマンスを理解するために、アプリケーションのオペレーションの健全性を監視したいと思っています。しかし、多くの場合、ウェブ アプリケーションから関連データを集めるのは困難です。本日は、OpenCensus Web(OC Web)を紹介します。OC Web を使うと、簡単かつ自動的にウェブ アプリケーションのインストルメンテーションを行い、指標や分散トレースをエクスポートすることができます。
OpenCensus Webライブラリは、ブラウザで実行されるフロントエンド ウェブ アプリケーションのコードに特化した OpenCensus の実装です。OC Web はウェブページのインストルメンテーションを行い、遅延や分散トレースなどのパフォーマンス データをユーザーサイドで収集します。デベロッパーは、フロントエンドの問題診断とアプリケーション全体の健全性監視のための情報を得ることができます。
なお、OC Web 以上に重要なのは、さらに広範な OpenCensus ファミリーのプロジェクトが OpenTracing を取り込んで OpenTelemetryになりつつあることです。このプロジェクトの準備が整った時点で、OpenCensus Web の機能は OpenTelemetry JSに移行される見込みです。その間も、OC Web はアルファ版リリースとして動作し続けます。
![]()
最初のページ読み込みにおけるすべての相互作用の時間を測定するため、OC Web はドキュメントの load イベントが発生するまで待機し、最初のページ読み込みパフォーマンスを示すタイミングからスパンを生成します。その際に、ブラウザの Navigation Timing API と Resource Timing API を使います。以下に示すのは、最初の読み込みサンプルアプリからキャプチャした OC Web のトレース サンプルを Zipkinにエクスポートしたものです。ブラウザの load イベントが発行されるまでのユーザーのナビゲーションの全体を表す ‘nav./’スパンがあることに注目してください。
このサンプルには、クライアント サイドとサーバーサイドで最初の HTML 読み込みを測定した ‘/’スパンも含まれています。これらのスパンは、W3C Trace Context形式で ‘window.traceparent’変数を送り返すサーバーによって接続されます。これが必要になるのは、ブラウザは最初のページ読み込みの際に Trace Context ヘッダーを送信しないためです。サーバーサイドのスパンから、テンプレートの解析とレンダリングにかかった時間もわかります。
先ほどのイメージの long js task スパンは、CPU による制約を受ける JavaScript イベントループに 80.095 ミリ秒かかったことを示しています。これは、Long Tasksブラウザ API で計測しています。
![]()
このルートスパンに名前を付けるため、デベロッパーが要素に data-ocweb-id属性を追加して操作の名前をカスタマイズできるようにしています。次の例では、‘Save edit user info’という名前になります。
functionhandleClick() {
詳細については、OC Web のドキュメントをご覧ください。
Reviewed by Yoshifumi Yamaguchi - Developer Relations Team
OpenCensus Web は、ユーザーがウェブページのパフォーマンスをどのように感じているかをトレースし、監視するツールです。診断方法がわからないパフォーマンスの問題がウェブページで発生していないかどうかを判断する際に役立ちます。
ウェブ アプリケーションの所有者は、実際のユーザーが感じるパフォーマンスを理解するために、アプリケーションのオペレーションの健全性を監視したいと思っています。しかし、多くの場合、ウェブ アプリケーションから関連データを集めるのは困難です。本日は、OpenCensus Web(OC Web)を紹介します。OC Web を使うと、簡単かつ自動的にウェブ アプリケーションのインストルメンテーションを行い、指標や分散トレースをエクスポートすることができます。
背景
OpenCensusプロジェクトは、いくつかの言語固有のインストルメンテーション ライブラリを提供しています。これらのライブラリは、アプリケーションからトレースや指標を収集し、Prometheus、Zipkin、Jaeger、Stackdriver などのトレースおよび監視バックエンドにエクスポートします。OpenCensus Webライブラリは、ブラウザで実行されるフロントエンド ウェブ アプリケーションのコードに特化した OpenCensus の実装です。OC Web はウェブページのインストルメンテーションを行い、遅延や分散トレースなどのパフォーマンス データをユーザーサイドで収集します。デベロッパーは、フロントエンドの問題診断とアプリケーション全体の健全性監視のための情報を得ることができます。
なお、OC Web 以上に重要なのは、さらに広範な OpenCensus ファミリーのプロジェクトが OpenTracing を取り込んで OpenTelemetryになりつつあることです。このプロジェクトの準備が整った時点で、OpenCensus Web の機能は OpenTelemetry JSに移行される見込みです。その間も、OC Web はアルファ版リリースとして動作し続けます。
アーキテクチャ
OC Web は、次の 3 つのアプリケーション コンポーネントと連係して動作します。- フロントエンド ウェブサーバー: OC Web のライブラリ コードや構成を含む最初の HTML をブラウザに対してレンダリングします。通常、これは OpenCensus サーバーサイド ライブラリ(Go、Java など)でインストルメンテーションされます。サーバーには、HTTP/JSON トレースを受信して OpenCensus Agent との通信を仲介するエンドポイントを作成することをお勧めします。
- ブラウザの JS: ブラウザで実行される OC Web ライブラリのコードです。このコードは、ユーザー操作の測定とブラウザデータの収集を行い、HTTP/JSON を使って OpenCensus Agent にスパンとして書き込みます。
- OpenCensus Agent: フロントエンド ウェブサーバーのプロキシ エンドポイントから、またはブラウザの JS から直接トレースを受け取り、トレース バックエンド(例: Stackdriver、Zipkin)にエクスポートします。
機能
最初のページ読み込みのトレース
OC Web を使うと、最初のページ読み込みのトレースを取得できます。なんと、OC Web ライブラリがブラウザに読み込まれる前に発生したイベントも取得できます。最初のページ読み込みのトレースを行うと、どのリソースがウェブサイトのパフォーマンスを低下させているのかがわかります。また、通常は分散トレース システムで取得できないデータも取得できます。最初のページ読み込みにおけるすべての相互作用の時間を測定するため、OC Web はドキュメントの load イベントが発生するまで待機し、最初のページ読み込みパフォーマンスを示すタイミングからスパンを生成します。その際に、ブラウザの Navigation Timing API と Resource Timing API を使います。以下に示すのは、最初の読み込みサンプルアプリからキャプチャした OC Web のトレース サンプルを Zipkinにエクスポートしたものです。ブラウザの load イベントが発行されるまでのユーザーのナビゲーションの全体を表す ‘nav./’スパンがあることに注目してください。
このサンプルには、クライアント サイドとサーバーサイドで最初の HTML 読み込みを測定した ‘/’スパンも含まれています。これらのスパンは、W3C Trace Context形式で ‘window.traceparent’変数を送り返すサーバーによって接続されます。これが必要になるのは、ブラウザは最初のページ読み込みの際に Trace Context ヘッダーを送信しないためです。サーバーサイドのスパンから、テンプレートの解析とレンダリングにかかった時間もわかります。
DOM イベントとネットワーク イベントのスパンのアノテーション
OC Web が取得するスパンには、詳細なアノテーションも含まれています。たとえば、`domInteractive`や `first-paint`などの DOM イベントについてのアノテーションや、domainLookupStart や secureConnectionStart などのネットワーク イベントについてのアノテーションです。次に示すのは、先ほどと同じトレースを Stackdriver Traceにエクスポートし、アノテーションを展開したものです。ユーザー操作
単一ページ アプリケーションでは、最初の読み込み後に操作(例: ユーザーがボタンをクリックする、ページの別のセクションに移動する)が発生するのが一般的です。エンドユーザーがブラウザ アプリケーション内で行った操作を測定すると、アプリケーションについて次のような有用なデータが得られます。- 最初のページのレンダリングとその後のページ内操作を関連付ける
- クリック後にページの応答がなくなるなど、エンドユーザーが認識できる速度低下を可視化する
クリック イベントの自動トレース
ブラウザの clickイベントは、DOM 要素(例: ボタン)がクリックされ、クリック対象の要素が無効になっていない限り、すべてトレースされます。ユーザーが要素をクリックすると、新しい Zoneが作成され、操作にかかる合計時間が計測されます。このルートスパンに名前を付けるため、デベロッパーが要素に data-ocweb-id属性を追加して操作の名前をカスタマイズできるようにしています。次の例では、‘Save edit user info’という名前になります。
<button type="submit"data-ocweb-id="Save edit user info"> Save changes </button>
これにより、特定の要素に関連するトレースを区別しやすくなり、似たような操作があっても明確に区別できるようになります。この属性を追加しない場合、OC Web は DOM 要素の ID、タグ名、操作に関連するイベント名を組み合わせたものを使います。たとえば、次のボタンをクリックすると、
<button id="save_changes"> Save changes </button>“button#save_changes click”という名前のスパンが生成されます。
ルート遷移の自動トレース
OC Web は、History APIにモンキーパッチを適用することで、ページ セクション間のルート遷移をトレースします。OC Web は、‘Navigation /path/to/page’というパターンを使ってこの操作に名前を付けます。次のスクリーンショットは、ユーザー操作サンプルから Stackdriver にエクスポートしたトレースです。ここには 1 つの Navigation トレースが含まれており、ルート遷移が完了する前にいくつかのネットワーク呼び出しが行われています。
![]()
カスタム スパンの作成
OC Web では、ユーザーの操作に関連するタスクやコードのカスタムスパンを使ってウェブ アプリケーションのインストルメンテーションを行うことができます。次に示すのは、その方法を例示したコード スニペットです。import { tracing } from'@opencensus/web-instrumentation-zone';
functionhandleClick() {
// 現在の操作のルートスパンの子スパンを開始
// これはボタンが実行するコードで実行する必要がある
constchildSpan= tracing.tracer.startChildSpan({
name:'name of your child span'
});
// 何らかのオペレーションを実行...
// オペレーション終了時に子スパンを終了
childSpan.end();
}
詳細については、OC Web のドキュメントをご覧ください。
HTTP リクエストの自動スパンとブラウザのパフォーマンス データ
OC Web は、ユーザーの操作によって生成される HTTP リクエストを自動的にインターセプトしてスパンを生成します。さらに、OC Web はインターセプトしたそれぞれの HTTP リクエストに W3C Trace Context形式の Trace Context ヘッダーを追加します。この処理は、同じオリジンのリクエストまたは提供された正規表現に一致するリクエストに対してのみ行われます。
サーバーで OpenCensus によるインストルメンテーションも行っている場合、バックエンド サービス全体でこれらのリクエストのトレースが継続されます。そのため、問題がフロントエンドにあるのかサーバーサイドにあるのかを知ることができます。
OC Web には、domainLookupStartや responseEnd などのアノテーションを作成し、CORS プリフライトリクエストのスパンを生成するための Performance APIデータも含まれています。
次のスクリーンショットは、ユーザー操作のサンプルとして Stackdriver にエクスポートしたトレースを示しています。アノテーションが付加されたスパンが自動生成されているネットワーク呼び出しがいくつか(例: ‘Sent./sleep’)あることがわかります。また、サーバーサイドのスパン(例: ‘/sleep’、‘ocweb.handlerequest’)や、CORS プリフライトに関連するスパンも存在します。
![]()
次のスクリーンショットは、initial_load_trace_id属性を使った検索を示しています。これには、最初にページを読み込んだ後のすべてのユーザー操作のトレースが含まれています。
![]()
投稿者: Cristian González – OpenCensus チーム – 2019 年夏季 Google ソフトウェア エンジニアリング インターン、コロンビア国立大学コンピュータおよびシステム エンジニアリング学部生
OC Web の最初の作成者であり、今回の開発のサポートをしてくれた Dave Raffensperger 氏に格別の感謝を捧げます。
サーバーで OpenCensus によるインストルメンテーションも行っている場合、バックエンド サービス全体でこれらのリクエストのトレースが継続されます。そのため、問題がフロントエンドにあるのかサーバーサイドにあるのかを知ることができます。
OC Web には、domainLookupStartや responseEnd などのアノテーションを作成し、CORS プリフライトリクエストのスパンを生成するための Performance APIデータも含まれています。
次のスクリーンショットは、ユーザー操作のサンプルとして Stackdriver にエクスポートしたトレースを示しています。アノテーションが付加されたスパンが自動生成されているネットワーク呼び出しがいくつか(例: ‘Sent./sleep’)あることがわかります。また、サーバーサイドのスパン(例: ‘/sleep’、‘ocweb.handlerequest’)や、CORS プリフライトに関連するスパンも存在します。
ユーザー操作と最初のページ読み込みのトレースとの関連付け
OC Web は、属性およびスパンリンクとして、ユーザーの操作に最初のページ読み込み時のトレース IDを付加します。これにより、1 つの属性に対するクエリでトレースを検索することで、最初の読み込みのトレースとその操作に関連するトレースを探せるようになります。また、あるページを読み込んだ後のアプリケーション内でのユーザーのナビゲーション全体を理解することも可能です。次のスクリーンショットは、initial_load_trace_id属性を使った検索を示しています。これには、最初にページを読み込んだ後のすべてのユーザー操作のトレースが含まれています。
実現する
OC Web を使えば、数行のインストルメンテーションを記述するだけで、ウェブ アプリケーションの分散トレースをエクスポートできます。ぜひ、最初の読み込みとユーザー操作のサンプルを試してみてください。ソースコードに手を入れてみたり、Gitterからフィードバックを送ったり、プル リクエストで貢献したりすることも大歓迎です!投稿者: Cristian González – OpenCensus チーム – 2019 年夏季 Google ソフトウェア エンジニアリング インターン、コロンビア国立大学コンピュータおよびシステム エンジニアリング学部生
OC Web の最初の作成者であり、今回の開発のサポートをしてくれた Dave Raffensperger 氏に格別の感謝を捧げます。
Reviewed by Yoshifumi Yamaguchi - Developer Relations Team