昨日に引き続きApplication Insightsネタです。
前回に引き続きJavaからApplication Insightsを使う際の備忘録です。今回はWebアプリケーションのリクエストをApplication Insightsに記録したいと思います。またWebアプリといっても様々なものがあるのですが、ここではSpring Boot を対象です(それが一番楽だから)
プロジェクトの用意
Spring Initializr を使ってひな形を作成しましょう。最近は、Visual Studio Codeから仕える拡張もあるので、そちらから利用してみるのも良いかもしれません。
このとき、後で必要な依存を含められるのですが、それは手動でやってきます。
依存
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
からのリクエストが記録されているとおもいます。展開すると詳しい記録を見ることが出来ます。
このように、とくにプログラムに手を入れることなくいくつかのテレメトリを自動で収集できるようになります。
ログ出力
上記の設定のみですと、前回のようなログがApplication Insightsに記録されません。同じ設定(依存とlogback.xml)をすればちゃんとログが飛びます。 ただし、 logbac.xml の中にインストルメンテーションキーの設定はしなくてもよいです。別のを設定するとどういう挙動をするのかは知らないです
内部実装
SDKの実装的な話をすると、以下のあたりでリクエスト、レスポンスのフィルター処理をしています。内部実装が気になる方は参考にしてください。
- ApplicationInsights-Java/HttpServerHandler.java at master · microsoft/ApplicationInsights-Java
- https://github.com/microsoft/ApplicationInsights-Java/blob/master/web/src/main/java/com/microsoft/applicationinsights/web/internal/WebRequestTrackingFilter.java
リクエストテレメトリにカスタムプロパティを追加する
テレメトリにはカスタムプロパティを追加できるのですが、そのコンテキストでの該当テレメトリインスタンスを取得する方法を紹介します。例えば、独自ヘッダやなどを一緒に記録したい場合に役立つかもしれません。
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"; } }
まとめと参考
前回も説明したとおり2.6.x系 と 3.0 previewがあるのですが、ぶっちゃけ3.0 から完全なエージェント方式っぽくなるようで、いずれ2.6.x系は廃れていくのかもしれません(不正確)とはいえ、自分でテレメトリ弄りたい場合もあるだろうし。
つづく...