しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Application Insights の Code Optimizations 機能を ASP.NET Core アプリケーションで試してみた

少し前から Application Insights の Performance を開くと、上部に Code Optimizations というボタンが表示されるようになっています。隣にある Profiler は以前からある機能ですが、Code Optimizations はひっそりと追加された新しい機能となります。

あまり注目されている気配を感じないのですが、上手く有効化出来ると継続的にアプリケーションのパフォーマンスを解析し、改善するというループを回しやすくなるはずです。ドキュメントがあるので、こちらも目を通しておくのが良いです。ちなみに現在サポートされているのは .NET のみです。

後で触れますが、Code Optimizations を利用するには Profiler を有効化する必要があります。この有効化方法が少し悩ましいので後半でまとめておきました。

Code Optimizations と Profiler で同じような機能を提供していますが、Profiler はトレースを収集するのがメインで、その結果は自分で解析・調査する必要があるのに対して、Code Optimizations は Profiler のトレースを AI ベースで自動解析してくれるので、パフォーマンス解析の知識が少なくても扱えるのが特徴です。

上手く有効化出来ていると Code Optimizations を開くと一覧が表示されるようになります。

自動的にグルーピングしてくれるので問題点を把握しやすいです。回数や影響度も同時に確認できるので、影響度の高いものから優先して対応するといったことも容易です。

一覧から項目を選ぶと更にドリルダウンして詳細を確認できます。スタックトレース込みで問題点についての詳細が AI ベースで生成されているので、アプリケーションのパフォーマンス改善に役立ちます。今回はサンプルなので ASP.NET Core 側の問題点が出てきましたが、通常のアプリケーションならユーザーコード側の問題点が検出されることが多いはずです。

影響度についてもグラフで表示してくれるので、検出された問題点にどのくらいのインパクトがあるのかをすぐに把握できます。閾値は AI によって自動的に判断されているようです。

Code Optimizations は Application Insights の機能であり、App Service の機能ではないため Profiler を有効化出来れば何処でも利用可能です。今回は App Service で試していますが、以下のドキュメントにもある通り Profiler 自体は様々な環境で有効化出来ます。

軽く触っただけですが、単なる APM ではなく AI ベースで問題の検出と解決策についても提案してくれる Code Optimizations は試してみる価値があると言えます。課題としては Application Insights Profiler の有効化が少し難しいというぐらいです。

ここから先は Code Optimizations というよりも Application Insights Profiler を有効化する方法をメモしておきます。特に App Service で利用する場合に悩むので、最適な設定を探る意味もあります。

ASP.NET Core 向けに Application Insights を有効化する方法

今回は ASP.NET Core 向けの話になりますが、App Service との組み合わせでは App Service に組み込まれた自動インストルメンテーションを使う方法と SDK をアプリケーションに組み込む方法があります。

詳細は以下のドキュメントに任せますが、それぞれの方法には特徴があるので最適なものを選んでいただければと思います。個人的には SDK をインストールする方法をフィルタリングなど高度なカスタマイズが可能なのでお勧めしています。

重要なのは Application Insights Profiler を有効化する方法は Application Insights の有効化方法に依存するという点です。混在はサポートされていないようなので注意が必要です。

App Service 組み込みの App Insights Profiler を有効化する

まずは非常にシンプルな App Service 組み込みの Application Insights Profiler を有効化する方法ですが、これはほぼ説明が要らない気がしますのでドキュメントを紹介するぐらいで行きます。

Application Insights 自体を App Service で有効化していれば、Application Insights Profiler も Azure Portal からポチっと有効化するだけで終わります。非常にシンプルですがカスタマイズは出来ません。

有効化後に Profiler の実行ログを確認して、正しくトレースが送信されているかを確認すれば終わりです。しばらく待てば Code Optimizations の方にも何かしらの検出結果が表示されるはずです。

もし正しく動作していないように見える場合は、以下のドキュメントにある通り診断ツールを使って、正しく Application Insights の Agent が読み込まれているか確認してください。

原因としてはアプリケーション側に Application Insights SDK が組み込み済みというのが多いですが、その辺りについても診断ツールは検出してくれます。

SDK をインストールして App Insights Profiler を有効化する

ASP.NET Core アプリケーションに Application Insights SDK をインストールするのはよく行われていると思いますが、この場合 App Service に組み込みの Application Insights Profiler は使えないので、NuGet で公開されている Profiler をインストールします。

この方法は Linux や Container 環境向けで紹介されていますが、Windows + SDK の組み合わせでも問題なく動作します。ドキュメントがあるのでこちらも参照してください。

設定方法は NuGet から Microsoft.ApplicationInsights.Profiler.AspNetCore をインストールすることから始めます。このパッケージに Profiler の実装が含まれているのでサイズは少し大きくなります。

パッケージをインストールした後は以下のように Startup.cs などで DI にサービスを追加するだけで終わります。Application Insights SDK がインストール済みの場合は AddServiceProfiler だけを追加します。

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// この 2 行を追加する
builder.Services.AddApplicationInsightsTelemetry();
builder.Services.AddServiceProfiler();

var app = builder.Build();

これでデフォルトの設定で Profiler が有効化されて、ランダムで Profiling が実行されるようになります。

細かいカスタマイズ項目については GitHub でドキュメントが公開されているので、必要に応じて設定を追加してもらえれば問題ありません。この辺りも SDK を使う上でのメリットですね。

App Service にデプロイする際には Application Insights の接続文字列が設定されていることを確認します。App Service で Application Insights を有効化すると App Settings に大量のキーが追加されてしまいますが、SDK の場合は以下のようにシンプルな設定で済みます。

こちらも Azure Portal から Profiler の実行ログを確認すると、正しく動作しているのか分かります。デフォルトではランダムで動くようになっているので、そこそこログは表示されるはずです。

これで SDK を利用している場合でも Application Insights Profiler を有効化出来たので、同じように Code Optimizations を利用できるようになります。どちらの方法も簡単ですが、カスタマイズ性とアプリケーションに組み込み可能かの観点で選ぶのが良いです。

App Service と SDK で Profiler を有効化した際の違い

ここまで紹介した 2 つの方法はどちらを使っても Profiler と Code Optimizations は利用可能になりますが、実際には細かい違いがあります。特に分かりやすい点だと生成されるトレースのフォーマットが .diagsession.netperf で異なります。

App Service の方は Visual Studio で標準的に使われる .diagsession が出力され、SDK の方は dotnet-trace で使われる .netperf が出力されます。

VS Code などで開発している場合には .netperf ファイルの方がビジュアライズの方法が柔軟なので、こちらの方が良いかもしれません。VS を持っている場合は一応どちらも読めそうです。

後は地味に気になる Profiler の負荷ですが、雑に App Service を 2 つ作成して確認したところ、App Service で有効化するよりも SDK で有効化した方が CPU 負荷は低いようでした。

この差が付いているのは Profiler の実装方法の差によると考えていて、App Service で有効化すると Profiler のプロセスが常に立ち上がっているのと、Profiling 方式の違いで高めになっている可能性があります。

本番環境では CPU 負荷を出来るだけ下げたいので、そういう意味でも SDK で有効化した方が良さそうです。