Azureの小ネタ (改)

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

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

JavaからApplication Insightsを使うための備忘録です。執筆時点で、2.6.x 系と 3.0 Preview がありますが、順に記録しておきたいと思います。

いくつかのユースケースはありますが、今回は単にプレーンなログをApplication Insightsに転送したい場合についてで、メトリクスとかは無視し、最小構成かつ2.6.x 系を使用して話をすすめます。

ライブラリ

2.6.x系では、Application Insights用へログを吐くためのライブラリにはいくつかあって、これはJavaのログ周りの話に関連しており、結果以下の3つ (logback/log4j2/log4j) があります。

好みに応じて使い分けてもらえれば良いと思います。実際に依存をつければあとは、slf4jから扱えると思います。

ここらの関係性は、ここをご一読ください。SLF4J、Logback、Log4Jの関係を挙動とともに整理する - Qiita

Application Insightsの用意

PortalからApplication Insightsを作成し、インストルメンテーションキーを用意します。

プロジェクトの準備

適当にプロジェクトを作って、 applicationinsights-logging-logback に依存を通しましょう。お好きなビルドツールを使えば良いと思いますが、ここでは mavenで進めます。

以下をpom.xmlに追加します。

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>applicationinsights-logging-logback</artifactId>
    <version>2.6.1</version>
</dependency>

これで必要なライブラリは以上です。 applicationinsights-core や他のlogbackslf4jへの依存は含まれています。

logbackの設定

logbackの設定は、src/main/resource/logback.xml に行います。以下はまるっとConsoleAppenderとApplication Insights Appenderのサンプルです。

インストルメンテーションキーは <instrumentationKey> に設定します。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE logback>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="aiAppender" class="com.microsoft.applicationinsights.logback.ApplicationInsightsAppender">
        <instrumentationKey>インストルメンテーションキー</instrumentationKey>
    </appender>
    <root level="info">
        <appender-ref ref="aiAppender"/>
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

ログ出力

ログの出力はフレームワークのロギングの作法に従って出力すれば、Application Insights に飛ばされます。HTTP/HTTPSを通してAzure上に転送されるので、Proxy環境化の場合は注意してください。

以下は、debug/info/war/errorとメッセージを繰り返し出力するだけのサンプルです。errorのみ例外をキャッチして引数に指定しています。例外を引数に与えない場合はトレーステレメトリに、例外がある場合は例外テレメトリに飛ばされます(これはSDKがそういう実装になっているというだけの話)。

Application Insightのデータモデルについては以下を参考にしてください。 Azure Application Insights Telemetry のデータ モデル - Azure Monitor | Microsoft Docs

package com.example;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {

    private static Logger log = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) throws InterruptedException {

        System.out.println("Hello Application Insights World!");

        for (int i = 0; i < 10; i++) {

            log.debug("Debug");
            log.info("Info");
            log.warn("Warn");

            try {
                var content = Files.readString(Paths.get("c:\\notexists"));
                System.out.println(content);
            } catch (IOException e) {
                log.error("error", e);
                log.error("non exception error");
            }
            Thread.sleep(500);
        }
    }
}

実行結果です。debugが出てないのは、info以上に設定しているためです。

15:11:21.526 [main] INFO  com.example.App - Info
15:11:21.527 [main] WARN  com.example.App - Warn
15:11:21.529 [main] ERROR com.example.App - error
java.nio.file.NoSuchFileException: c:\notexists
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:370)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:421)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3205)
        at java.base/java.nio.file.Files.readString(Files.java:3283)
        at java.base/java.nio.file.Files.readString(Files.java:3242)
        at com.example.App.main(App.java:24)

Application Insights SDK のTelemetryクラスを使って飛ばす方法もありますが、単なるログについては既存のフレームワークの作法に従った方が問題が少ないと思います。

Azure ポータルでの確認

Application Insightsから検索メニューを開くと、ざっくり直近のログが確認できます。もっと高度なことがしたい場合はログから色々なクエリが実行できます。

f:id:StateMachine:20200730153052p:plain

次回はWebアプリのあたりを(つづく)。