Application InsightsでAngularのページ読み込み時間は測れるのか?
なんでやるの?
フロントエンド(Angular)にAzure Application Insightsを入れてページビューを計測してみた - cougerの日記 の残ってる課題を調べてみようと思った。
分かったこと
切り替え時間を知りたい場合は、startTrackPage と stopTrackPage を使う。
trackPageViewではページ切り替えの時間を計測できない。
なんで?
trackPageViewで引数のDurationを指定しなかった場合、Application Insightsは Navigation Timing を使ってページの読み込み時間を計測する。 コードはこの辺。
- trackPageViewは、Telemetry.PageViewPerformanceを使って計測データを採取
https://github.com/Microsoft/ApplicationInsights-JS/blob/c5cbccf42e709f497c7c9a8b74663dd38d8ed55d/dist/ai.0.23.4.js#L3251 - Telemetry.PageViewPerformanceは、自身のメソッド getPerformanceTiming を呼び出し、計測結果を取得
https://github.com/Microsoft/ApplicationInsights-JS/blob/c5cbccf42e709f497c7c9a8b74663dd38d8ed55d/dist/ai.0.23.4.js#L2835 - PageViewPerformance.getPerformanceTimingは、window.performance.timingをそのまま返却
https://github.com/Microsoft/ApplicationInsights-JS/blob/c5cbccf42e709f497c7c9a8b74663dd38d8ed55d/dist/ai.0.23.4.js#L2869
Navigation Timingとは?
Navigation Timingとはブラウザがウェブサイトを表示するまでの間の一連のプロセスとタイミングを細かく定義したもので、Unload,Redirect,Fetch,DNSLookup,TCPConnect,Request,Response,Processing,Loadという処理プロセスとなっており、それぞれの境目にもStart及びEndというタイミングがあります。
この実装がNavigation Timing APIで、Navigation Timing APIとはこれらのタイミング毎に到達した時間を、それぞれUnixTimestampで取得できるというものです。
Navigation Timingを軸にJavascriptの実行タイミングを理解する - Qiita
「ブラウザがウェブサイトを表示するまでの間」なので、表示した後の画面の切り替えは計測ができない。そりゃそうだ。
じゃ、どうすんの?
startTrackPage と stopTrackPage を使う。
Navigation Timing APIを使わず、start, stopまでの時間を計測してくれる。
ApplicationInsights-JS/API-reference.md at master · Microsoft/ApplicationInsights-JS · GitHub
どこに埋め込むべきか?
startTrackPageはコンポーネントのOnInitか、ルーターのNavigationEndで良いんじゃないかと思う。
stopTrackPageは、OnInitの後、どこまでの時間を測りたいかによるんだろうけど、Serviceでデータを取得した後、DOMのレンダリングが終わるまでを測りたい場合、どこに仕込めばいいのか分からない。困った。
Serviceでデータを取得するところまででよいなら、 subscribe のコールバックで stopTrackPage を呼べばいいと思う。
全部のコンポーネントに入れるのタルい
だよねぇ...。とはいえ、コンポーネントごとに呼び出すサービスの種類や数が違うから、基底クラスを作ってそこで呼び出せばOKってわけでもなさげ。
今思いつくもので、一番影響が少ないのは、
- 計測をあきらめて、画面切り替えが始まったとき(RouterのNavigationEndや、RouterOutletのonActivateなど)で trackPageView を呼び出す。
- Durationを0にしておいたほうがいいかも。
かなぁ。 この方法でも、Application Insightsがページに関連するRequestの時間は計測してくれる(正確には違うんだけど)から、Requestに要した時間の合計までは計算できるはず。
Application Insightsで収集したフロントエンドとバックエンドのデータを関連づける (未解決)
方法知ってたら、教えてください!!!
お礼に、ハトマスクあげます。
回避策を中の人に聞けたりすると嬉しいんだけどなぁ。
なんでやるの?
低速なリクエストの診断ができるようになると楽になるんじゃないかなーと。
こんな感じでまとめてくれるっぽい。
あとまぁ、つなげられそうだから、つなげてみたい。(手段が先行するタイプ)
目標
ページビューからSQLまで計測結果がつながればいいかな。こんな感じ。
* ページビュー (取れてる) * 依存(AJAX) (取れてる) * リクエスト (取れてる) * 依存(SQL) (取れてない)
どうやってやるの?
Azure Application Insights Telemetry の相関付け | Microsoft Docs が参考になる。
さっきの構造だと、以下のようになればOK。
type | id | operation_Id | operation_ParentId |
---|---|---|---|
ページビュー | aaa | aaa | |
依存(AJAX) | 111 | aaa | aaa |
リクエスト | 222 | aaa | 111 |
依存(SQL) | 333 | aaa | 222 |
- ページビューのoperation_Idを全てのtypeで利用する
- operation_ParentIdは、呼び出し元のidを使う。
わかっていること
ページビュー -> 依存(AJAX)の所は、Application Insightsのライブラリがいい感じで関連付けてくれていた。(operation_Idも、operation_ParentIdも適切な値が設定されている)
なので、リクエスト -> 依存(SQL)の方もうまくできるに違いない。
とすれば、残りは依存(AJAX)とリクエスト、つまり、フロントエンドとバックエンドをつなげるところだけをなんとかすればいいはず。
調べること
以下の2点の実装方法。
- フロントエンドからoperation_Idと、operation_ParentIdをバックエンドに送る方法
- バックエンドで受け取った値を使って、Applicaton Insightsにデータを送る方法
フロントエンド
実装されているようだ。
// Default true. If false, the SDK will add two headers ('x-ms-request-root-id' and 'x-ms-request-id)
// to all dependency requests (within the same domain) to correlate them with corresponding requests on the server side.
disableCorrelationHeaders: boolean;
API Reference
ただ、デベロッパーツールで確認するとヘッダが追加されてない。検索したらIssueが上がってた。
クロスドメインの場合は動かないらしい。残念。
Java側の方も検索したら以下のIssueが上がってたんだけど...
Headers X-ms-request-id and X-ms-request-root-id are deprecated. Please do not use them for the fresh implementation. They can cause problems with Azure Storage REST API calls.
Also please support Request-Context header for http request and response. It is widely used for app-id propagation.
See http://apmtips.com/blog/2017/10/18/two-types-of-correlation/ and https://docs.microsoft.com/en-us/azure/application-insights/application-insights-correlation
x-ms...は使わないで、Request-Context使ってねってことみたい。ヒェェェェェ。
なんか沼にはまりそう。
バックエンド
フロントエンドから送ってきたデータをOperationIdとして使う場合、カスタムのInitializerクラスを実装して、ApplicationInsights.xmlに設定したWebOperationIdTelemetryInitializerと入れ替えれば良さそう。
実装方法は、WebOperationIdTelemetryInitializer を参考にすれば良い。operation_ParentIdは、setParentIdで設定できる...んじゃないかな?
フロントエンドよりは希望がもてそう。
と、ここで体力と気力が切れたので、調査はおしまいにする。
さぁ、DEAD OR ALIVE Xtreme Venus Vacation やるぞー!!
バックエンド(Spring Boot)にAzure Application Insightsを入れてリクエストを計測してみた
Spring Bootって何?
もう書かなくてもいいんじゃないかな?? (誰に言われたわけでもないけど)
https://projects.spring.io/spring-boot/projects.spring.io
導入方法
前回同様、GitHubにあったSpring Frameworkのサンプルアプリpetclinicを使い、Azure Application Insights を使用した Java Web アプリの分析 | Microsoft Docs を見ながら導入した。 最初の一歩を開発元が用意してくれてるのありがたい。
petclinicはSpring Framework定番のサンプルアプリっぽい。コミュニティで色んな派生アプリを作っている模様。
コード
GitHubに置いてみた。
https://github.com/nobiinu-and/spring-petclinic-rest/tree/monitoring-request
変更点はここで確認できる。
試行錯誤したところ
- Application Insightsのログを出せるようにした
- Application InsightsのInstrumentation Keyを外出しした
Application Insightsのログを出せるようにした
Application Insightsの設定ファイルに以下を加えれば良い。
<SDKLogger> <Type>CONSOLE</Type> </SDKLogger>
思いつきだったのに、探すの結構苦労した...orz
Application InsightsのInstrumentation Keyを外出しした
環境変数 "APPLICATION_INSIGHTS_IKEY" で指定すれば、勝手に読み込んでくれるので、修正点はなし。
Application Insights SDK は、次の順序でキーを探します。
システムのプロパティ: -DAPPLICATION_INSIGHTS_IKEY=your_ikey
環境変数: APPLICATION_INSIGHTS_IKEY
構成ファイル: ApplicationInsights.xml
見えるようになったもの
ガイドにあるようなデータが取れてる。
残ってる課題
SQLとかの実行時間知りたい
Azure Application Insights における依存関係の追跡 | Microsoft Docsを見ると、SQLの実行時間なども分析してるんだけども...。追加の設定が必要なのかな?
Performance monitoring for Java web apps in Azure Application Insights | Microsoft Docs この辺が参考になりそう。Agentを別立てする必要がありそうなので、今回はパス。
出力しているログも分析したい
Azure Application Insights を使用した Java トレース ログの探索 | Microsoft Docsに書いてあった。 logbackの設定を変更すればいいらしい。
参考にしたページ
フロントエンド(Angular)にAzure Application Insightsを入れてページビューを計測してみた
Angularって何?
Angularは、Googleとオープンソースコミュニティで開発されているJavaScriptフレームワークです。 AngularJSと呼ばれていたバージョン1(AngularJS 1)から、バージョン2で大きく変更されて、以降はAngularと呼ばれています。 バージョン2時点では「Angular 2」と呼ばれることもありましたが、現在はAngularが正式名称です。
JavaScriptフレームワーク「Angular」新バージョン4の変更点と今後の展望 (1/3):CodeZine(コードジン) より引用。
会社のとあるチームの人たちが使ってるんだけど、最近モニタリングに取り組み始めて、Applicaiton Insightsを使ってる。
個人的にもやらないとなーと思いつつ、手がつけられてなかったので、ちょうどいい機会だからのっかった感じ。
導入方法
手頃なアプリがなかったので、GitHubにあったSpring Frameworkのサンプルアプリpetclinicを使い、Add Application Insights to an Angular SPA – Premier Developer を見ながら導入した。
petclinicはSpring Framework定番のサンプルアプリっぽい。コミュニティで色んな派生アプリを作っている模様。
マイクロサービス版もある!! Kubernetes + Istioの練習するときに使ってみよう :D
コード
GitHubに置いてみた。
変更点はここで確認できる。
試行錯誤したところ
- webpackをインストールした
- logPageViewの引数を指定した
- Application InsightsのInstrumentation Keyを外出しした
webpackをインストールした
基本、インストールはREADMEの手順に沿って行う。
最後の ng serve
でエラーが起きた(メモ忘れたので詳細がわからん)ので、npm install --save-dev webpack
をして、webpackをインストールして解決。
logPageViewの引数を指定した
logPageViewはtrackPageViewをラッパーしたもの。
引数を指定しない場合、Application Insightsはページ名にWindowのタイトルを利用する。
サンプルアプリはページごとにWindowのタイトルが変わらないので、コンポーネントの名前を入れてみることにした。
コンポーネント(クラス)の名前は this.constructor.name
で指定できる。
Application InsightsのInstrumentation Keyを外出しした
KeyをGitHubで晒すのもなぁと思った(というか、晒してたので慌てて削除した)ので、 Angular 4 で Connection String や Secret を Environment Variables から取得する - Qiitaを参考に外出し。
残ってる課題
全ての画面を対象にする
Add Application Insights to an Angular SPA – Premier Developer にも書かれてるけど、記載されている方法だとコンポーネントごとにコードを記述する必要がある。
コンポーネントの基底クラスを作って、そっちで処理しろって書いてあるんだけど、なんか面倒。
以下のような感じで、ルーティングの NavigationStart イベントを使っても処理できるかもしれない?
(画面名がコンポーネント名の代わりにURLになっちゃうんだけども)
export class AppComponent { constructor(router: Router, private myMonitoringService: MyMonitoringService) { router.events .filter((event) => event instanceof NavigationStart) .subscribe((event: NavigationStart) => { this.myMonitoringService.logPageView(event.url); }); } }
一応実装してみた。動いてはいる模様。
ただ、この方法だとルートガードでキャンセルされた場合(実際に画面遷移しなくても)計測してしまう。
キャンセルされた場合の話を考えるといろいろ難しくなりそうなので、これで置いとくことにする。(別途、キャンセルしたことを通知すればいい気も)
Durationで計測されているのはどの処理なのか?
画面の切り替えは1秒以内で行われているんだけど、Durationで計測されてる時間は2秒以上かかってた。
ちなみに、バックエンドからデータを取ってくる時間は含まれていない(バックエンドの処理に細工して、5秒sleepさせたけど、その時間は含まれなかった)。
処理時間は参考程度にしておくって手もあるんだけど、なんかモニャモニャする。
参考にしたページ
Azure Application Insightsを入れてページビューを計測してみた
Application Insightsって何?
Azure Application Insights とは何か | Microsoft Docsを引用してみる。
Application Insights は、複数のプラットフォームで使用できるWeb 開発者向けの拡張可能なアプリケーション パフォーマンス管理 (APM) サービスです。 このサービスを使用して、実行中の Web アプリケーションを監視することができます。 パフォーマンスに異常があると、自動的に検出されます。 組み込まれている強力な分析ツールを使えば、問題を診断し、ユーザーがアプリを使用して実行している操作を把握できます。
AWSで言うと"CloudWatch"に当たるらしく、主にメトリクスの採取に使うらしい。
ページビューを計測するために適当なのかはよくわかんないけど、まぁいいんですよ!
AWSとAzureのサービス名対比表 | Ryuzee.com
導入方法
何が取れるか、どう取ればいいのかわからなかったので(マニュアルを読もう)、まずは計測したいページだけに入れてみて、取れたデータを眺めることにした。
Application InsightsをBasicプランで作成し、あとはGitHub - Microsoft/ApplicationInsights-JS: Microsoft Application Insights SDK for JavaScriptを見ながらページにJavaScriptを仕込めば良い。
ちょっと試行錯誤して、最終的に入れ込んだスクリプトは以下。
<script src="ai.0.js"></script> <script type="text/javascript"> var snippet = { config: { instrumentationKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" } }; var init = new Microsoft.ApplicationInsights.Initialization(snippet); var appInsights = init.loadAppInsights(); appInsights.setAuthenticatedUserContext("ユーザID"); appInsights.trackPageView("ページ名"); </script>
以下、試行錯誤したところ。
- Include AI JS SDK script and initialize statically を使ってApplication Insightsを入れた -> ai.0.js のトコ
- setAuthenticatedUserContextを使ってユーザIDを指定した
- trackPageViewの引数を指定した
Include AI JS SDK script and initialize statically を使ってApplication Insightsを入れた
Use JS snippet and initialize dynamically (download full Application Insights script from CDN) の方がお手軽なんだけど、 以下のAuthenticatedUserIdを指定する方法がわからなかったので、こちらに。
ファイルは npm install applicationinsights-js
を実行、node_modules/applicationinsights-js/dist
にできる ai.0.js
を使った。
ai.0.js
はminifyしたヤツ。minifyしてないのは ai.js
になる。
setAuthenticatedUserContextを使ってユーザIDを指定した
Facebookで以下のことを教えてもらったので、ユーザIDを指定することにした。
ありがとう! ボッチエンジニアの人!!!
ai.js とかが発行するuserIdはCookieに保存されてるので、その生存期間が過ぎたり、異なるブラウザからアクセスすると、同一ユーザーであってもApplication Insights 上では別ユーザー扱いになっちゃうんです。 なので、認証を終えたら、authenticated user id を付けてあげると、そういった問題が解決できるそうです。
trackPageViewの引数を指定した
引数を指定しない場合、Application Insightsはページ名にWindowのタイトルを利用する。
サイトのタイトルが長くて、結果画面が見づらかったので、カスタマイズすることにした。
最初から作るサイトであれば、こういうところも考慮に入れてタイトルどうするか考えた方がいいのかな?
見えるようになったもの
こんなのが見えるようになった。
個人的にはほったらかしてたエラーが分析されるようになって、「直さなきゃ」ってモチベーションが生まれた。
気になる料金
価格—Application Insights | Microsoft Azure によると、今回適用したBasicプランでは、
- 1GB/月までは無料
- それ以降は234.6円/GB
- データは90日間保持される。蓄積したデータをエクスポートしたい場合は51円/GB。
ということなので、まぁほぼお金かからない。助かる。
参考にしたページ
まずはここ。
APIリファレンスは同じサイトのApplicationInsights-JS/API-reference.md at master · Microsoft/ApplicationInsights-JS · GitHubにある。
Mob Programming の体験ができる/事例発表があるイベント
気が向いたら更新。
これから
体験できる
- 2017.07.22 - Agile Japan 2017 愛媛サテライト - connpass
- 2017.07.25 - モブプログラミング交流会 at ヴァル研究所
- 2017.07.27 - Mob Programming Val #1|TECH PLAY[テックプレイ]
- 2017.07.28 - Mob Programming at クリエーションライン - connpass
事例発表など
終わったもの
体験できる
- 2017.04.13 - AgileJapan2017
- 2017.04.24 - よちよち.rb 第124回 "よちよちモブプロ会" - よちよち(の心をずっとわすれない).rb | Doorkeeper0
- 2017.04.25 - DevOpsDays Tokyo 2017
- 2017.05.29 - モブプログラミングをやってみる - DevLOVE関西 | Doorkeeper
- 2017.06.19 - MobProgramming at ヴァル研究所さん
- 2017.07.01 - Coderetreat for Girls - connpass
- 2017.07.01 - 突発的イベント in Trailhead Live Tokyo - Tokyo Salesforce Developer Group (東京都) | Meetup
事例発表など
- 2017.06.18 - DevLOVE200 Bridge - DevLOVE | Doorkeeper
- 2017.07.11 - モブプロディスカッション | Eventbrite
Mob Programming のエントリまとめ (リンクだけ)
いちいち探すの面倒なので、まとめておこう。 ひとまずリンクだけ。
インタビュー
- モブプログラミング - Woody Zuill氏とのインタビュー
- チーム全員が1台のPCを共有するというモブ・プログラミングの実態。果たしてその効果とは?【バズワードから紐解くエンジニアのキャリア Vol.5】 - エンジニアtype | 転職@type
考察とか
- モブプログラミングが気になったので、なんとなくひろって集めてみた - Togetterまとめ
- CoolなソロとHotなペアプロのあいだ – 時を超えたプログラミングの道
- マネジメントにも技術力は必要。モブプログラミングのメリットとは?|ウェブ担当者通信
- (´-`).。oO(Mob Programming) - Mitsuyuki.Shiiba
- 内向的な人がモブプログラマになるのは難しいのか?
- モブプログラミングって何だ? - iyuichiの私的開発ログ
- モブ・プログラミングって開発手法が人気を集めつつあるらしいぞ : 汎用型自作PCまとめ
- Mob Programmingとは何者か?これはすぐに導入すべきだ - fuuno
- モブプログラミングを楽しむエンジニアをWanted!! - 株式会社レベルファイブのエンジニア中途・インターンシップの求人 - Wantedly
- 今はコードがお偉いさんなんだからMOBは雁首揃えろって話
- 技術なきマネジメントの衰退とその対策 - メソッド屋のブログ
動画
- A day of Mob Programming - YouTube
- A day of Mob Programming 2016 - YouTube
- A DAY OF MOBBING at Agile Japan 2017 - YouTube
やってみた
- モブプログラミングを試してみてわかった事|ネスケラボ
- モブプログラミングやってみたら最高だった #MobProgramming - ジムには乗りたい
- (なんちゃって)モブ・プログラミング(もどき)でスキル伝授をしてみた
- (なんちゃって)モブ・プログラミング(もどき)を何回か実践しての気づき
- (なんちゃって)モブ・プログラミング(もどき)の比較
- モブプログラミングを実際にやってみた - Qiita
- 流行りのモブプログラミングをやって分かった 個人の開発手法の違い - Qiita
- 社内でモブプログラミングやってみた #mobprogramming - クリエーションライン株式会社
- モブプログラミングをやってみた | Engineer Blog | 株式会社エムティーアイ
- 夏到来!みんなで飛び込もう モブプログラミング の海へ!!〜Backlogチームの場合〜 | ヌーラボ
- モブプログラミングおためし会をやってみた | Goalist Developers Blog
- モブプログラミングというものを体験してきた
- ガイアックスで10年、エンジニアとして感じたこと | Gaiax official website
- 取り組みを始めたとのこと
やってみた @ Agile Japan 2017
- モブプロって楽しい! - hi, hikaru
- AgileJapan2017でモブプログラミングに飛び入り参加しました。 - Akiyahの日記
- モブプログラミングをするマシンにMobsterが入ると最高だった | Recruit Jobs TECHBLOG