Blazor WebAssembly に Azure Application Insights を組み込む

# Azure Application Insights とは

Azure Application Insights とは、マイクロソフトのパブリッククラウドサービス「Microsoft Azure」上で提供されている、"アプリケーションパフォーマンス管理" サービスのひとつです。
アプリケーション上で発生するさまざまな "状況データ" (以降 **"テレメトリ"** と記載します) を、インターネットを経由して Azure 上の Application Insights サービスへ送信・集約することで、実行中のアプリケーションの監視を実現するものです。

App Insights サービスへのテレメトリ送信の仕掛けをアプリケーションに組み込むことで、異常の検出、問題の診断、ユーザー操作の把握を、Azure ポータル画面上などで可能とします。

詳しくは下記公式ドキュメントを参照ください。

- ["Azure Application Insights とは何か - Azure Monitor | Microsoft Docs"](https://docs.microsoft.com/ja-jp/azure/azure-monitor/app/app-insights-overview)

ということで、では、この Azure Application Insights へのテレメトリ送信の仕掛けを、Blazor WebAssembly アプリに仕込んでみたいと思います。

# [BlazorApplicationInsights](https://www.nuget.org/packages/BlazorApplicationInsights) NuGet パッケージが頼みの綱

アプリケーションから Azure Application Insights へテレメトリ送信するための機能は、Java や Python、Node.js、そしてもちろん C# (ASP.NET) などなど、大抵の各種言語や処理系用に "SDK" が用意されています。

そのため、それら言語・処理系においては、Azure Application Insights の SDK (つまるところ、それら言語・処理系における "ライブラリ") をアプリケーションに組み込み、その SDK で提供されるクラスや関数などを使ったコードを数行書き足して、テレメトリ送信をセットアップすればよいです。

Blazor WebAssembly においても状況は同じですが、ただし、**Microsoft からの標準・公式の SDK の提供**は (今のところ) **ありません**。

そのため、Blazor WebAssembly アプリに Azure Application Insights のテレメトリ送信機能を組み込むには、現在のところ、下記オープンソース (MIT ライセンス) の NuGet パッケージ「**BlazorApplicationInsights**」の利用が妥当な状況です。

- ["NuGet Gallery | BlazorApplicationInsights"](https://www.nuget.org/packages/BlazorApplicationInsights)

組み込み手順は、この NuGet パッケージの GitHub リポジトリ (下記 URL) に記載があります。

- https://github.com/IvanJosipovic/BlazorApplicationInsights

# 実際に組み込んでみた結果

試しに、ASP.NET Core ホスト上の小さな Blazor WebAssembly プロジェクトを作り、上記 GitHub リポジトリに記載の手順に沿って、Azure Application Insights のテレメトリ送信機能を組み込んでみました。

また、この ASP.NET Core ホスト + Blazor WebAssembly のアプリには、わざと、捕捉されない例外が発生するような仕掛けを施しておきました。
捕捉されない例外の Azure Application Insights 上での記録の様子を見てみようと思ったためです。

さてひととり実装を終え、アプリケーションをビルド、ローカルで実行し、操作して、捕捉されない例外の発生を引き起こしてみました。

その上で、Web ブラウザで Azure ポータル画面 (https://portal.azure.com/) にサインインし、Application Insights のダッシュボードを開いて、この手元でローカル実行し例外を発生させた Blazor WebAssembly のテレメトリが表示されるか見てみました。

なお、テレメトリ送信後、Application Insights サービスでそのテレメトリが取りまとめられて、**Azure ポータル画面で見られるようになるまで数分かかります**ので、暫し待ちます。

今回は、Azure ポータル画面の Application Insights のブレードから、「Failures (失敗)」のカテゴリを開き、「Browser」のビューに切り替えて見てみました。

すると、ちゃんと捕捉されない例外の発生が記録されていました (下図)。
![fig001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58450/9c69e735-2ec4-c869-8d32-a02a6d53a4b1.png)
さらにそれら例外の項目を選択して画面を開いていくと、**「どういうページを渡り歩いて、この例外の発生に至ったのか」のタイムライン**や、**例外の詳細情報**を見ることができました (下図)。
![fig002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58450/d7f50938-8fb5-4b54-714a-5f550015d7bf.png)

# 感想

「BlazorApplicationInsights」NuGet パッケージを使うことで、Blazor WebAssembly アプリに、Azure Application Insights へのテレメトリ送信の機能を組み込むことができました。

その結果、Blazor WebAssembly アプリ上で捕捉されない例外が発生しても、Azure ポータル画面から、例外発生までの経緯や、例外情報を見ることができるようになりました。

ただ、本当に些細な事ながら、少々残念に感じる点もありました。

## 例外情報が構造化されていない

Azure Application Insights に記録された例外情報の形式上、"Message" も "Exception Type" も、**例外オブジェクトをまるっと文字列化 (`ToString()`) した内容、つまり、スタックトレースも含めた文字列として記録されている**のは、ちょっと残念なところです。

## 組み込みの手順が煩雑?

あと、難しくはないとはいえ、組み込みの手順がちょっと多いなー、と感じました。

とくに、

- JavaScript コード片を、Microsoft 公式 Application Insights JavaScript SDK の GitHub リポジトリにある [README](https://github.com/microsoft/ApplicationInsights-JS#snippet-setup-ignore-if-using-npm-setup) からコピペさせて、かつ、パラメータ部分の書き換えが必要なあたりとか、
- 同 NuGet パッケージに同梱の JavaScript ファイル `_content/BlazorApplicationInsights/JsInterop.js` を読み込む `script` タグを `index.html` に追記するとか、

そういった JavaScript 連携周りのセットアップが手間に感じました。

まぁ、BlazorApplicationInsights NuGet パッケージを無償で使わせてもらっているのに、あんまり偉そうにしては罰が当たるというものです 😅

ただ、自分が作成して公開している NuGet パッケージは、「なるべく利用者の手間をかけないように」という点も重視して作っていたりする自分の性格・嗜好もあって、そんな感想を持ちました。
上記 JavaScript 周りの "不満" については「こういう実装にすれば作業不要になるのでは?」というアイディアもあるため、時間と機会があれば、フィードバックしたい気持ちはあります。

## ASP.NET Core サーバー側が原因の例外のとき

Blazor WebAssembly アプリ側からホストしている ASP.NET Core サーバー側の Web API を `HttpClient` を使って呼び出した際に、そのサーバー側で捕捉されない例外が発生した場合、Azure ポータル画面を自分が操作した限りでは、ブラウザ側はブラウザ側、サーバー側はサーバー側、で、別々のタイムラインでしか表示することができませんでした。

Azure Application Insights では、SPA 側のページビューの記録から、サーバー側での例外の発生に至るまでを、ブラウザ側・サーバー側を統合したタイムラインで見ることはできなかったでしょうか?

これは Azure Application Insights の仕様なのか、BlazorApplicationInsights NuGet パッケージの制約・限界なのか、そのあたりの切り分けも、今のところよくわかっていません。

もしなにか情報お持ちでしたら、コメントいただけるとありがたいです!

_Learn, Practice, Share!_