目次
Application Insights
Application Insights は Azure Monitor の機能であり、開発者や DevOps プロフェッショナル向けの拡張可能なアプリケーション パフォーマンス管理 (APM) サービスです。 このサービスを使用して、実行中のアプリケーションを監視することができます。 パフォーマンスの異常を自動的に検出し、組み込まれている強力な分析ツールを使用して、問題を診断し、ユーザーがアプリを使用して実行している操作を把握できます。 Application Insights は、パフォーマンスやユーザビリティを継続的に向上させるうえで役立つように設計されています。 オンプレミス、ハイブリッド、または任意のパブリック クラウドでホストされている .NET、Node.js、Java、Python などのさまざまなプラットフォーム上のアプリで機能します。 DevOps プロセスと統合され、さまざまなツールへの接続ポイントを備えています。 Visual Studio App Center と統合することで、モバイル アプリからテレメトリを監視および分析できます。
Application Insights は、Azure プラットフォーム上に限った話ではなく、ASP.NET/ASP.NET Core Web アプリケーション以外に Java、JavaScript、Node.JS、Pyhon などの言語や、Android、iOS向けにもSDKが提供されています。
今回は、WPF から Telemetry を送信する方法を紹介します。
非HTTPアプリケーション向け
上記サイトでは、Webアプリケーション以外の3種類のアプリケーションについて説明しています。
.NET Core 3.0 ワーカーサービス
.NET Core 3.0 でマイクロサービス関連のバックグラウンド処理を目的とした Worker Service プロジェクトが追加されました。実行時間が長いサービスを、Windows サービスとして実行します。IHostedService を使用した ASP.NET Core のバックグラウンドタスク .NET Core 2.0 以降 IHostedService が提供され、バックグラウンドプロセスで処理するタスクを簡単に実装できるようになっています。
.NET Core / .NET Framework コンソール アプリケーション .NET Core 2.0 以上、もしくは .NET Framework 4.7.2 以上で利用できます。コンソールアプリケーションとなっていますが、WPFでも使用可能です。
検証環境
手順
パッケージのインストール
NuGet で Microsoft.ApplicationInsights.WorkerService
をインストールします。
間違えずに WorkerService が付いているものを選びます。
実装
まずは全文です。
IServiceCollection services = new ServiceCollection(); services.AddLogging(builder => builder.AddFilter<ApplicationInsightsLoggerProvider>("WpfApp1", LogLevel.Information)); services.AddApplicationInsightsTelemetryWorkerService("instrumentationkeyhere"); IServiceProvider serviceProvider = services.BuildServiceProvider(); var logger = serviceProvider.GetRequiredService<ILogger<SampleClass>>(); var telemetryClient = serviceProvider.GetRequiredService<TelemetryClient>(); var httpClient = new HttpClient(); // 実際はTelemetryを送信する期間≒アプリケーションのライフサイクルに合ったロジックが必要 //while (true) { logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); using (telemetryClient.StartOperation<RequestTelemetry>("operation")) { logger.LogWarning("A sample warning message. By default, logs with severity Warning or higher is captured by Application Insights"); logger.LogInformation("Calling bing.com"); var res = await httpClient.GetAsync("https://bing.com"); logger.LogInformation("Calling bing completed with status:" + res.StatusCode); telemetryClient.TrackEvent("Bing call event completed"); } await Task.Delay(1000); } telemetryClient.Flush(); Task.Delay(5000).Wait();
続けて細部を見ていきます。
IServiceCollection services = new ServiceCollection(); services.AddLogging(builder => builder.AddFilter<ApplicationInsightsLoggerProvider>("WpfApp1", LogLevel.Information)); services.AddApplicationInsightsTelemetryWorkerService("instrumentationkeyhere");
ServiceCollection
は、Microsoft.Extensions.DependencyInjection
名前空間にあるDIコンテナです。
そこに ApplicationInsightsLoggerProvider
を使用して、ILogger
のログをキャプチャするように設定します。
ILoggingBuilder
でフィルターを追加しています。後で Logger
を取得する時に Type
をカテゴリ名として指定しますが、その Type
の FullName のプレフィックスと一致させることで、出力するログレベルを制御することができます。
今回はアプリケーションの名前空間が Wpf1App
であり SampleClass
もその配下に定義されています。また、LogLevel
は Information
なので、Information
以上の Level のログが出力されることになります。
一致するフィルターがない Logger
の場合は、既定値の Warning
以上のログが出力されるようになります。
"instrumentationkeyhere" はよしなに取得、設定するようにして下さい。
ILogger
のログをキャプチャする必要がなく、 TelemetryClient
だけを使用する場合はよりシンプルになります。必要なのは次のコードの部分だけです。
IServiceCollection services = new ServiceCollection();
services.AddApplicationInsightsTelemetryWorkerService(key);
IServiceProvider serviceProvider = services.BuildServiceProvider();
var telemetryClient = serviceProvider.GetRequiredService<TelemetryClient>();
次に、ServiceProvider
をビルドして、Logger
のインスタンスを取得します。
IServiceProvider serviceProvider = services.BuildServiceProvider(); var logger = serviceProvider.GetRequiredService<ILogger<SampleClass>>(); var telemetryClient = serviceProvider.GetRequiredService<TelemetryClient>();
カテゴリ名として指定する Type
は、Application Insights にもカテゴリとして出力されます。
ILogger
に定義されている汎用的なログ出力以外に、Application Insights で使われる詳細なログを出力するために、TelemetryClient
を使います。
残りの後半部分についてです。
RequestTelemetry
は using
で囲ったログと依存関係が収集され親子関係を持つログとして関連付けられます。依存関係はログだけでなく、外部コンポーネント、つまりHTTP を使用して呼び出されるサービス、またはデータベース、あるいはファイル システムも追跡されます。追跡される依存関係をいかに示します。
また、StartOperation()
を使う方法は、依存関係を手動で追跡する方法に該当します。
依存関係 | 詳細 |
---|---|
Http/Https | ローカルまたはリモートの http/https 呼び出し |
WCF 呼び出し | Http ベースのバインディングを使用する場合にのみ自動追跡されます。 |
SQL | SqlClient で行われる呼び出し。 SQL クエリのキャプチャについてはこちらを参照してください。 |
Azure Storage (BLOB、テーブル、キュー) | Azure Storage Client で行われる呼び出し。 |
EventHub Client SDK | バージョン 1.1.0 以上。 |
ServiceBus Client SDK | バージョン 3.0.0 以上。 |
Azure Cosmos DB | HTTP/HTTPS が使用されている場合にのみ、自動的に追跡されます。 TCP モードは、Application Insights ではキャプチャされません。 |
Application Insights での見え方は、後段の実行結果を確認してみてください。 「DEPENDENCY」として登録されているデータが追跡結果になります。
アプリケーションを終了する場合は、Telemetry が送信完了するために Flush()
を呼び出す必要があります。通常は、30秒毎、または500アイテムが溜まってからデータを送信するようです。
実行結果
サンプルコードの出力結果です。
以下は、RequestTelemetry
の詳細です。
タイムラインで処理時間を見ることができます。また、RequestTelemetry
で囲った内容だけが集約されているのが分かります。
一致するフィルタがない場合は、 Warning
以上が出力されるようになります。