Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

JavaからAzure Application Insightsを使う(2)

昨日に引き続きApplication Insightsネタです。

前回に引き続きJavaからApplication Insightsを使う際の備忘録です。今回はWebアプリケーションのリクエストをApplication Insightsに記録したいと思います。またWebアプリといっても様々なものがあるのですが、ここではSpring Boot を対象です(それが一番楽だから)

プロジェクトの用意

Spring Initializr を使ってひな形を作成しましょう。最近は、Visual Studio Codeから仕える拡張もあるので、そちらから利用してみるのも良いかもしれません。

f:id:StateMachine:20200731102118p:plain
Generate spring boot application

このとき、後で必要な依存を含められるのですが、それは手動でやってきます。

依存

Spring Boot向けに、 Azure Application Insights Spring Boot Starter が用意されているのでこれを利用します。適宜Bootアプリ向けの設定を行ってくれます。

Maven Repository: com.microsoft.azure » applicationinsights-spring-boot-starter » 2.6.1

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>applicationinsights-spring-boot-starter</artifactId>
    <version>2.6.1</version>
</dependency>

実はこの依存元になる applicationinsights-web ライブラリがあるのですが、このstarter は Spring Boot ラッパーだと思っていただければ良いと思います。ApplicationInsights.xml での設定ではなく、application.yaml (properties) などで設定可能になっています。

したがって、Bootアプリでなければ上記への依存とApplication.xmlの設定で同じようにテレメトリが取得出来ると思います。(Bootアプリでもstarter使わずwebを使えます)

設定

src/main/resources/application.yamlに以下の設定します。インストルメンテーションキー以外に spring.application.nameを設定しておくと、テレメトリのCloud Role Name プロパティにアプリ名が記録されます。

spring:
    application:
        name: MyWebApplication
azure:
    application-insights:
        instrumentation-key: インストルメンテーションキー

ソース

適当にリクエストを受け付けられるように修正します。 取りあえず文字列を返すだけの簡単なAPIです。ログへの記録とかは必要なく、リクエストがApplication Insightsにリクエストテレメトリとして記録されます。

package com.example.web.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @RequestMapping("/")
    public String home() {
        return "Hello Application Insights World";
    }
}
mvn clean package spring-boot:run

で実行して、localhost:8080/に何度かアクセスしてみてください。記録されるまで数分の遅延があるので注意してください(前回言ってなかった気がする)

Azure ポータルでの確認

localhostからのリクエストが記録されているとおもいます。展開すると詳しい記録を見ることが出来ます。

f:id:StateMachine:20200731102217p:plain
request

このように、とくにプログラムに手を入れることなくいくつかのテレメトリを自動で収集できるようになります。

ログ出力

上記の設定のみですと、前回のようなログがApplication Insightsに記録されません。同じ設定(依存とlogback.xml)をすればちゃんとログが飛びます。 ただし、 logbac.xml の中にインストルメンテーションキーの設定はしなくてもよいです。別のを設定するとどういう挙動をするのかは知らないです

内部実装

SDKの実装的な話をすると、以下のあたりでリクエスト、レスポンスのフィルター処理をしています。内部実装が気になる方は参考にしてください。

リクエストテレメトリにカスタムプロパティを追加する

テレメトリにはカスタムプロパティを追加できるのですが、そのコンテキストでの該当テレメトリインスタンスを取得する方法を紹介します。例えば、独自ヘッダやなどを一緒に記録したい場合に役立つかもしれません。

ApplicationInsights SDK が用意するThreadContextクラスにリクエストテレメトリを取得する静的メソッドがあるので、順次取り出していきます。getPropertyでカスタムプロパティが取り出せますのでputで設定するだけす。ここでは、リクエストを受けるメソッドで直接やっていますが、定型処理ならばSpringの機能であるインターセプターの仕組みで常に記録するのがいいかもしれません。

@RestController
public class HomeController {

    private final Logger log = LoggerFactory.getLogger(HomeController.class);

    @RequestMapping("/")
    public String home() {
        log.info("info message");

        var telemetory = ThreadContext.getRequestTelemetryContext().getHttpRequestTelemetry();
        telemetory.getProperties().put("Some Cusome Property", (new Date().toString()));

        return "Hello Application Insights World";
    }
}

f:id:StateMachine:20200731102313p:plain
custom property

まとめと参考

前回も説明したとおり2.6.x系 と 3.0 previewがあるのですが、ぶっちゃけ3.0 から完全なエージェント方式っぽくなるようで、いずれ2.6.x系は廃れていくのかもしれません(不正確)とはいえ、自分でテレメトリ弄りたい場合もあるだろうし。

つづく...