しばやん雑記

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

Azure Functions から送信される Application Insights テレメトリにバージョンを付ける

勝手に付いてるだろうと思っていましたが、Azure Functions の場合は Application Insights の各テレメトリにバージョンが付いていなかったので、ITelemetryInitializer を使ってカスタマイズすることにしました。

ASP.NET Core の場合はデフォルトで付いているので特に気にする必要はないです。Azure Pipelines と組み合わせて自動でバージョンを付ける場合は以下のエントリを参照してください。

バージョンをテレメトリに付けることで、自動的に Application Insights がグルーピングを行ってくれたり、Smart Detection が賢くなったりとメリットが多いです。

実際にログから Groupted results を開くと、アプリケーションのバージョンでグルーピングされています。

f:id:shiba-yan:20190820004911p:plain

バージョン管理を行うのはモニタリング面でも非常に重要なので、ちゃんと送っておきたいところです。

ASP.NET Core では簡単に設定できましたが、Azure Functions の場合はカスタム ITelemetryInitializer を使って解決しました。

ITelemetryInitializer を実装する

Azure Functions SDK には Application Insights SDK は含まれていないので、別途インストールする必要があります。バージョンは最新を使っておけば問題なさそうです。

最新のランタイムに含まれているバージョンを調べましたが v2.10 でした。

既に Application Insights のテレメトリに用意されているプロパティへバージョンをセットするだけなので、非常に簡単なコードになりました。

public class ApplicationVersionInitializer : ITelemetryInitializer
{
    public string ApplicationVersion { get; set; }

    public void Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Component.Version = ApplicationVersion;
    }
}

分かりにくいですが、アプリケーションのバージョンは Component.Version の値が使われます。

実装した Telemetry Initializer を DI に追加

Telemetry Initializer を実装すれば、後は DI に追加すれば Application Insights のパイプラインで使われます。

DI を使うためには、もはやお馴染みとなったパッケージをインストールすれば良いです。

DI には Singleton として追加します。インターフェースを指定しないと動かないので注意。

アセンブリからバージョンを取得する処理を Telemetry Initializer に入れても良かったのですが、型名からアセンブリを特定した方が分かりやすいのでプロパティで初期化するようにしました。

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton<ITelemetryInitializer>(new ApplicationVersionInitializer
        {
            ApplicationVersion = typeof(Startup).Assembly
                                                .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
                                                ?.InformationalVersion
        });
    }
}

特に説明することのない単純なコードでした。これでアセンブリのバージョンが Application Insights のテレメトリと一緒に送信されるようになります。

適当な Function App にデプロイして、Application Insights 側でテレメトリを確認しておきます。

f:id:shiba-yan:20190820002043p:plain

全てのテレメトリに Application Version が確認できますね。バージョン番号自体は分かりやすいように付けたので、特に意味のない値です。本来なら CI 側でバージョンを付けます。

Kusto を使ってアプリケーションのバージョン毎での集計も簡単に行えます。

f:id:shiba-yan:20190820002054p:plain

エラーレートやパフォーマンスに関係するメトリクスをアプリケーションのバージョン毎に集計して、グラフとして表示などすればトレンドが簡単に読み取れるので便利です。

特にパフォーマンス改善では、そのバージョンで本当に効果があったのかを検証できないと全く意味がないです。Azure Pipelines の Deployment job と組み合わせることで、デプロイされたコミットを一目で確認できるので更に便利になります。