LoginSignup
5
7

Spring Boot のログを出力する

Last updated at Posted at 2023-03-15

Spring Boot のログを出力する

こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu で Spring Boot Web アプリケーションのログを出力する方法を紹介します。
spring-boot_on_ubuntu.png

目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

実現すること

ローカル環境の Spring Boot アプリにログを出力する設定を組み込み、標準出力とファイルにログを出力します。

ログを出力する SLF4J 実装ライブラリには Logback を使用します。

技術トピック

SLF4J (Simple Logging Facade for Java) とは?

こちらを展開してご覧いただけます。

SLF4J (Simple Logging Facade for Java)

SLF4J
SLF4J は、Java アプリケーションで使用されるオープンソースのロギングフレームワークです。SLF4J は、ログ記述に関する Java のAPI を抽象化して、アプリケーションのコードをロギングフレームワークに依存しない形で書くことを可能にします。つまり、アプリケーションが複数のロギングフレームワークに依存することなく、ロギング機能を使用できるようになります。
Logback
Logback は、SLF4J API を実装するバックエンドの1つです。つまり、SLF4J API を使用してログを出力するアプリケーションで、Logback をバックエンドとして使用することができます。Logback は、高速で柔軟性があり、多くの機能を提供するロギングフレームワークであり、SLF4J と組み合わせて使用することで、一貫性のあるログ記述を維持することができます。

したがって、SLF4J と Logback は、アプリケーションのロギング機能を改善するために一緒に使用されることが一般的であり、組み合わせて使用することで、柔軟性、パフォーマンス、一貫性のあるログ出力を提供することができます。

開発環境

  • Windows 11 Home 22H2 を使用しています。

WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。

WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます

> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47

Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04

Java JDK ※ こちらの関連記事からインストール方法をご確認いただけます

$ java -version
openjdk version "11.0.18" 2023-01-17
OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)

Maven ※ こちらの関連記事からインストール方法をご確認いただけます

$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.18, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64

この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。

作成する Web アプリケーションの仕様

No エンドポイント HTTPメソッド MIME タイプ
1 /api/data GET application/json
説明を開きます。

/api/data というエンドポイントに対して HTTP GET リクエストを送信すると、JSON データがレスポンスされるシンプルな Web サービスを実装します。

ログを出力する手順

Spring Boot アプリの作成

こちらの関連記事からご確認いただけます。

プロジェクトフォルダに移動

プロジェクトフォルダに移動します。
※ ~/tmp/hello-spring-boot をプロジェクトフォルダとします。

$ cd ~/tmp/hello-spring-boot

※参考: Spring MCV などの場合

Spring Boot では、pom.xml に依存を追加する必要はありません。

ログを出力するライブラリを追加 (Spring MVC など)

pom.xml の修正

pom.xml を編集します。

$ vim pom.xml

ファイルの内容

pom.xml ※一部抜粋
<!-- Log -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>

LogBack を使用する場合、通常 logback-corelogback-classic の2つの依存関係を含める必要があります。これらの依存関係には、ログ記録機能と SLF4J (Simple Logging Facade for Java) の実装が含まれています。したがって logback-classic は SLF4J に依存し、logback-core は logback-classic に依存します。

Spring Boot の設定ファイルを追加

application.properties ファイルを作成します。

$ mkdir -p src/main/resources
$ vim src/main/resources/application.properties

ファイルの内容

application.properties
spring.profiles.active=develop
説明を開きます。

spring.profiles.active は、Spring Boot アプリのプロファイルを設定するためのプロパティの一つです。このプロパティは、アプリの起動時にアクティブにするプロファイルを指定するために使用されます。

内容
develop 例えば develop プロファイルには、開発時に便利な機能やロギングレベルが DEBUG に設定されるような設定が含まれる場合があります。
production 一方、本番環境での動作に適した設定が含まれる production プロファイルを指定することもできます。

ログ設定ファイルを追加

Spring Boot アプリケーションでは、デフォルトで src/main/resources ディレクトリにある logback-spring.xml ファイルが自動的に読み込まれます。

logback-spring.xml ファイルを作成します。

$ vim src/main/resources/logback-spring.xml

ファイルの内容

logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <springProfile name="develop">
        <include resource="org/springframework/boot/logging/logback/defaults.xml" />
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>[%-5le] %lo{0}.%M:%L - %msg%n</pattern>
            </encoder>
        </appender>

        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>./log/app.log</file>
            <append>true</append>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>./log/app.%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>5MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>31</maxHistory>
                <cleanHistoryOnStart>true</cleanHistoryOnStart>
            </rollingPolicy>
            <encoder>
                <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%-5le] [%t] %C.%M:%L - %m%n</pattern>
            </encoder>
        </appender>

        <logger name="org.springframework" level="INFO" />
        <logger name="com.example" level="DEBUG" />

        <root level="WARN">
            <appender-ref ref="STDOUT" />
            <appender-ref ref="FILE" />
        </root>
    </springProfile>

</configuration>
説明を開きます。
logback-spring.xml ※一部抜粋
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />

この設定は Spring Boot ロギングのデフォルト設定ファイルをインクルードしています。※参考: 公式 Spring Boot ロギングのデフォルト設定

logback-spring.xml ※一部抜粋
<pattern>[%-5le] %lo{0}.%M:%L - %msg%n</pattern>

この設定はログ出力のフォーマットを指定しています。

表記 意味
%le ログイベントのレベル
%lo ロガー名
%M メソッド名
%L 行番号
%msg ログメッセージ本体
%n 改行
logback-spring.xml
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%-5le] [%t] %C.%M:%L - %m%n</pattern>

この設定はログ出力のフォーマットを指定しています。

表記 意味
%date{yyyy-MM-dd HH:flag_mm:ss.SSS} ログが出力された日時を指定されたフォーマットで表示します。
%-5le ログレベルを5文字の幅で表示します。%-5は左揃えを指定するためのフラグです。
%t ログを出力したスレッド名を表示します。
%C.%M:%L ログを出力したクラス、メソッド、行番号を表示します。
%m ログメッセージを表示します。
%n 改行を挿入します。
logback-spring.xml ※一部抜粋
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>./log/app.%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
    <timeBasedFileNamingAndTriggeringPolicy
        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>5MB</maxFileSize>
    </timeBasedFileNamingAndTriggeringPolicy>
    <maxHistory>31</maxHistory>
    <cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>

この設定は、時間単位でログファイルをローテーションする方法を指定しています。

内容
ログファイル名は ./log/app.%d{yyyy-MM-dd}_%i.log.gz ファイル名パターンに従って命名されます。
また SizeAndTimeBasedFNATP クラスを使用して、ファイルサイズと時間に基づくローテーションを設定しています。
ログファイルの最大サイズは 5MB に設定されており、maxHistory プロパティを使用してログファイルの最大保存日数を 31 日に設定しています。
cleanHistoryOnStart プロパティはアプリケーションの起動時に古いログファイルを自動的に削除するかどうかを設定します。

Java コードにログを出力するコードを追加

Java ソースコードを編集します。

$ vim src/main/java/com/example/springboot/controller/HelloController.java

ファイルの内容

HelloController.java
package com.example.springboot.controller;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

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

    @GetMapping("/data")
    public Map<String, String> getData() {
        Map<String, String> map = Map.of("message", "Hello World!");
        log.info("Hello World!");
        return map;
    }
}
説明を開きます。
HelloController.java ※一部抜粋
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

SLF4J を使用して Java のログを出力するために必要なクラス、インタフェースをインポートしています。

HelloController.java ※一部抜粋
private static final Logger log = LoggerFactory.getLogger(HelloController.class);

LoggerFactory.getLogger() メソッドには、ロギング機能を使用するクラスの名前を渡します。通常、クラス単位でロガーを定義するためクラスの完全修飾名を指定します。このロガーオブジェクトは、SLF4J を通じてログ出力のために使用されます。

HelloController.java ※一部抜粋
log.info("Hello World!");

SLF4J の Logger インタフェース info() メソッドを呼び出してログにメッセージ "Hello World!" を出力しています。

SLF4J のログレベル

レベル 概要
TRACE デバッグに使用される非常に詳細な情報
DEBUG デバッグ情報
INFO 一般的な情報
WARN 警告情報
ERROR エラー情報
FATAL 致命的なエラー

プロジェクトの構成

プロジェクトのファイル構成を表示してみます。

$ tree -I log -I target
.
├── pom.xml
├── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── springboot
        │               ├── Application.java
        │               └── controller
        │                   └── HelloController.java
        └── resources
            ├── application.properties
            └── logback-spring.xml

アプリのビルド

Java アプリをビルドします。(※ 参考)
※ target/app.jar が作成されます。

package フェーズで作成される app.jar がなくても、spring-boot:run フェーズを使用してアプリケーションを起動できます。したがって、package フェーズは必須ではないことに注意してください。

$ mvn clean package

アプリを起動

アプリを起動します。
※ アプリを停止するときは ctrl + C を押します。

$ mvn spring-boot:run

ここまでの手順で、Ubuntu でアプリの JAR ファイルを起動することができました。

アプリの動作確認

別ターミナルから curl コマンドで確認します。

$ curl http://localhost:8080/api/data -w '\n'
{"message":"Hello World!"}

ターミナルに以下のようにログが表示されました。

[INFO ] HelloController.getData:20 - Hello World!

また、/log/app.log に以下のように追記されました。

2023-03-15 10:35:44.331 [INFO ] [http-nio-8080-exec-3] com.example.springboot.controller.HelloController.getData:20 - Hello World!

ここまでの手順で、標準出力ファイルログを出力することができました。

非同期でログを出力する設定

こちらを展開してご覧いただけます。

非同期バージョン logback-spring.xml

logback-spring.xml を修正します。

$ vim src/main/resources/logback-spring.xml

ファイルの内容

logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <springProfile name="develop">
        <include resource="org/springframework/boot/logging/logback/defaults.xml" />
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>[%-5le] %lo{0}.%M:%L - %msg%n</pattern>
            </encoder>
        </appender>

        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>./log/app.log</file>
            <append>true</append>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>./log/app.%d{yyyy-MM-dd}_%i.log.gz</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>5MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>31</maxHistory>
                <cleanHistoryOnStart>true</cleanHistoryOnStart>
            </rollingPolicy>
            <encoder>
                <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%-5le] [%t] %C.%M:%L - %m%n</pattern>
            </encoder>
        </appender>

        <logger name="org.springframework" level="INFO" />
        <logger name="com.example" level="DEBUG" />

        <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
            <appender-ref ref="STDOUT" />
            <includeCallerData>true</includeCallerData>
        </appender>

        <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
            <queueSize>512</queueSize>
            <neverBlock>false</neverBlock>
            <appender-ref ref="FILE" />
            <includeCallerData>true</includeCallerData>
        </appender>

        <root level="WARN">
            <appender-ref ref="ASYNC_STDOUT" />
            <appender-ref ref="ASYNC_FILE" />
        </root>
    </springProfile>

</configuration>

この例では、AsyncAppender を定義して、FILE アペンダーと STDOUT アペンダーを非同期に呼び出すように設定しています。

パラメータ 内容
queueSize 512 AsyncAppender が使用するキューのサイズを指定します。キューはログイベントを一時的に保持するために使用されます。設定値は必要に応じて調整できますが、設定値を大きくしすぎるとメモリ消費量が増加することがあります。
neverBlock false キューがいっぱいの場合にログイベントをブロックするかどうかを制御します。この値が true の場合、キューがいっぱいでもログイベントをブロックせずに破棄します。false の場合、キューがいっぱいの場合にはログイベントをブロックします。
includeCallerData true Logback のロギングイベントに呼び出し元情報(caller data)を含めるように設定するための設定です。呼び出し元情報とは、ログイベントが発生した場所(クラス名、メソッド名、行番号)を示す情報です。この設定を有効にすると、呼び出し元情報をロギングイベントに含めることができます。ただし、この設定は、パフォーマンスの観点から、非同期アペンダーを使用する場合には注意が必要です。

まとめ

Ubuntu に構築したシンプルな Java 開発環境で、Spring Boot Web サービスからログを出力することができました。

実際の業務での Spring Boot の使用ケースでは、構成ファイルなどが追加されるため、ここで示したようなシンプルな構成とは異なる場合があります。しかしながら、最小構成の例を学ぶことで、Spring Boot がどのような構成が必要なのかを理解することができます。

どうでしたか? WSL Ubuntu で、Spring Boot Web アプリケーションのログ出力の設定を、手軽に行うことができます。ぜひお試しください。今後も Java の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7