noxi雑記

.NET、Angularまわりの小ネタブログ

ASP.NET Coreアプリで特定のURLのみApplicationInsightsにログを送信しない

ASP.NET Core アプリでは NuGet からパッケージを導入することでサクッと ApplicationInsights にアクセスログを連携することができます。ただそのまま導入すると全てのアクセスデータを送信するため、例えば死活監視のエンドポイントに対するアクセスが全て記録されてしまうなどの問題が発生します。
この記事では特定の URL に対するアクセスを ApplicationInsights に送信する対象外とするための設定方法を紹介します。


TL;DR

  • ITelemetryProcessor を実装したクラスを作成し、 RequestTelemetry の中から特定の URL を持っている場合のみ除外する。
  • Startup#ConfigureServices の中でサービスに追加する。

前提条件

この記事は以下の環境で検証しています。

フィルターする処理の実装

docs.microsoft.com

このドキュメントにある通り、 TelemetryProcessor を実装することでテレメトリーが ApplicationInsights に送信する前に任意の処理を行う事ができます。今回は特定の URL のリクエステレメトリーを除外する処理を実装しますので、プロセッサー自体の実装はこのようになります。

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;

namespace ApplicationInsightsUrlFilterApp.ApplicationInsights
{
    public class UrlFilterTelemetryProcessor : ITelemetryProcessor
    {
        private readonly ITelemetryProcessor _next;

        public UrlFilterTelemetryProcessor(ITelemetryProcessor next)
        {
            // TelemetryProcessorの処理はチェインされるため
            // 次のプロセッサーをコンストラクターの引数で受け取る
            _next = next;
        }

        public void Process(ITelemetry item)
        {
            // リクエストテレメトリーのみを選別
            if (!(item is RequestTelemetry request))
            {
                _next.Process(item);
                return;
            }

            // 特定のリクエストかどうかを判定
            if (request.Context.Operation.Name == "GET Sample/GetFuga")
            {
                // 特定のリクエストだった場合、次のプロセッサーを実行しないことで
                // サーバーにデータが送信されない
                return;
            }

            _next.Process(item);
        }
    }
}

フィルターのかけかたはさておき、 Name に GET Sample/GetFuga が設定されたテレメトリーはサーバーに送信されなくなります。プロセッサーを実装する際はプロセッサー処理がチェインされることに注意し、次に実行されるプロセッサーコンストラクターの引数として受け取ります。そして処理を続ける場合は次のプロセッサーを呼び出します。

フィルターする処理の追加

ITelemetryProcessor はただ実装するだけでは効果を発揮せず、適切にテレメトリー送信パイプラインに組み込まねばなりません。 ASP.NET Core で実装する場合は Startup で依存サービスとして実装したプロセッサーを宣言することで自動的に組み込まれるようです。

using ApplicationInsightsUrlFilterApp.ApplicationInsights;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace ApplicationInsightsUrlFilterApp
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            ...

            // TelemetryProcessorを使用する設定
            services.AddApplicationInsightsTelemetryProcessor<UrlFilterTelemetryProcessor>();
        }

        ...
    }
}

IServiceCollection の拡張メソッドの AddApplicationInsightsTelemetryProcessor を、 Generics の引数に実装したプロセッサーを指定して呼び出します。
ちなみにサービス一覧に追加されているプロセッサーの呼び出し順がどうなるかは良く分かりませんでした。この辺りを眺める限りでは、サービス一覧に登録した順に呼び出されそうな気もします。