はじめに

Spring Bootアプリケーションを運用する上で、適切なログ設定は欠かせません。開発中のデバッグ、本番環境での障害調査、パフォーマンス監視など、ログはあらゆる場面で重要な役割を果たします。

Spring Bootでは標準でLogbackがログフレームワークとして組み込まれており、logback-spring.xmlを使用することでSpring Boot独自の拡張機能を活用した柔軟なログ設定が可能です。本記事では、Logbackの設定ファイルの書き方から環境別設定まで、実践的なログ設定手法を解説します。

前提条件

  • Java 17以上
  • Spring Boot 3.2以上
  • Maven または Gradle によるプロジェクト管理
  • Spring Webの依存関係(spring-boot-starter-web

logback-spring.xmlの構成要素

Spring Bootでは、src/main/resourcesディレクトリにlogback-spring.xmlを配置することでLogbackの設定をカスタマイズできます。logback.xmlではなくlogback-spring.xmlを使用する理由は、Spring Boot独自の拡張機能(<springProfile>タグなど)を利用できるためです。

基本構成

logback-spring.xmlの基本的な構成要素は以下の通りです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- プロパティ定義 -->
    <property name="LOG_PATH" value="./logs" />
    <property name="LOG_FILE" value="application" />
    
    <!-- Appender定義 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!-- Logger定義 -->
    <logger name="com.example.myapp" level="DEBUG" />
    
    <!-- Root Logger定義 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

主要な構成要素

要素 説明
<property> 設定ファイル内で使用する変数を定義
<appender> ログの出力先と形式を定義
<encoder> ログメッセージのフォーマットを定義
<logger> 特定パッケージやクラスのログレベルを設定
<root> すべてのロガーの親となるルートロガーを設定

パターンレイアウトの主要フォーマット

<pattern>で使用できる主なフォーマット指定子は以下の通りです。

フォーマット 説明
%d{pattern} 日時(例:%d{yyyy-MM-dd HH:mm:ss.SSS}
%thread スレッド名
%level / %-5level ログレベル(5文字幅で左寄せ)
%logger{n} ロガー名(nは文字数の上限)
%msg ログメッセージ
%n 改行
%X{key} MDC(Mapped Diagnostic Context)の値

Appenderの種類と設定

Logbackには複数のAppenderが用意されており、用途に応じて使い分けます。

ConsoleAppender

コンソール(標準出力)にログを出力します。開発環境での利用が主な用途です。

1
2
3
4
5
6
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

FileAppender

指定したファイルにログを出力します。シンプルなファイル出力に使用します。

1
2
3
4
5
6
7
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${LOG_PATH}/${LOG_FILE}.log</file>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

RollingFileAppender

ファイルサイズや日付に基づいてログファイルをローテーションします。本番環境では必須のAppenderです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_PATH}/${LOG_FILE}.log</file>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
        <maxFileSize>100MB</maxFileSize>
        <maxHistory>30</maxHistory>
        <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>
</appender>

ローリングポリシーによるログローテーション

本番環境では、ログファイルが際限なく肥大化することを防ぐため、ログローテーションの設定が重要です。

SizeAndTimeBasedRollingPolicy

サイズと時間の両方を条件としてログファイルをローテーションする、最も実用的なポリシーです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_PATH}/application.log</file>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- ローテーション後のファイル名パターン -->
        <fileNamePattern>${LOG_PATH}/application.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
        <!-- 1ファイルあたりの最大サイズ -->
        <maxFileSize>100MB</maxFileSize>
        <!-- 保持する世代数(日数) -->
        <maxHistory>30</maxHistory>
        <!-- ログファイル全体の最大サイズ -->
        <totalSizeCap>3GB</totalSizeCap>
        <!-- 起動時に古いログを削除するか -->
        <cleanHistoryOnStart>true</cleanHistoryOnStart>
    </rollingPolicy>
</appender>

ローリングポリシーのパラメータ

パラメータ 説明
fileNamePattern ローテーション後のファイル名。.gzを付けると自動圧縮
maxFileSize 1ファイルあたりの最大サイズ
maxHistory 保持するファイルの世代数(日数)
totalSizeCap 全ログファイルの合計最大サイズ
cleanHistoryOnStart アプリケーション起動時に古いログを削除

TimeBasedRollingPolicy

時間のみを条件としてローテーションする場合に使用します。

1
2
3
4
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOG_PATH}/application.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
    <maxHistory>30</maxHistory>
</rollingPolicy>

Spring Profileによる環境別設定

Spring Bootの<springProfile>タグを使用すると、開発環境と本番環境で異なるログ設定を適用できます。これはlogback-spring.xmlでのみ使用可能な機能です。

環境別設定の実践例

以下は開発環境(dev)と本番環境(prod)で異なる設定を適用する完全な設定例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
    
    <!-- Spring Bootのデフォルト設定を読み込み -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    
    <!-- 共通プロパティ -->
    <property name="LOG_PATH" value="${LOG_PATH:-./logs}" />
    <property name="APP_NAME" value="${spring.application.name:-application}" />
    
    <!-- コンソール出力(共通) -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%-5level) %clr([%15.15thread]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    
    <!-- 開発環境(dev)の設定 -->
    <springProfile name="dev">
        <!-- 詳細なログ出力 -->
        <logger name="com.example.myapp" level="DEBUG" />
        <logger name="org.springframework.web" level="DEBUG" />
        <logger name="org.hibernate.SQL" level="DEBUG" />
        <logger name="org.hibernate.orm.jdbc.bind" level="TRACE" />
        
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>
    
    <!-- 本番環境(prod)の設定 -->
    <springProfile name="prod">
        <!-- ファイル出力用Appender -->
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${LOG_PATH}/${APP_NAME}.log</file>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
                <charset>UTF-8</charset>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
                <maxFileSize>100MB</maxFileSize>
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
        </appender>
        
        <!-- エラーログ専用Appender -->
        <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${LOG_PATH}/${APP_NAME}-error.log</file>
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>ERROR</level>
            </filter>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
                <charset>UTF-8</charset>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/${APP_NAME}-error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
                <maxFileSize>50MB</maxFileSize>
                <maxHistory>90</maxHistory>
                <totalSizeCap>1GB</totalSizeCap>
            </rollingPolicy>
        </appender>
        
        <!-- 本番環境ではWARN以上のみ出力 -->
        <logger name="com.example.myapp" level="INFO" />
        <logger name="org.springframework" level="WARN" />
        <logger name="org.hibernate" level="WARN" />
        
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE" />
            <appender-ref ref="ERROR_FILE" />
        </root>
    </springProfile>
    
    <!-- デフォルト設定(プロファイル未指定時) -->
    <springProfile name="!dev &amp; !prod">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>
    
</configuration>

プロファイル式の記述方法

<springProfile>タグでは、複雑な条件を記述できます。

説明
name="dev" devプロファイルがアクティブな場合
name="dev | staging" devまたはstagingがアクティブな場合
name="!production" productionがアクティブでない場合
name="dev &amp; debug" devかつdebugがアクティブな場合(XMLでは&&amp;と記述)

application.propertiesとの連携

<springProperty>タグを使用すると、application.propertiesの値をLogback設定で使用できます。

1
2
3
4
5
6
7
8
<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="myapp" />
<springProperty scope="context" name="logLevel" source="logging.level.root" defaultValue="INFO" />

<property name="LOG_FILE" value="${appName}" />

<root level="${logLevel}">
    <appender-ref ref="CONSOLE" />
</root>

対応するapplication.propertiesの設定例です。

1
2
3
spring.application.name=my-rest-api
logging.level.root=INFO
logging.level.com.example.myapp=DEBUG

ログレベルの設定指針

適切なログレベルの設定は、効率的なデバッグと運用に不可欠です。

ログレベルの使い分け

レベル 用途
ERROR システムの異常、即座に対応が必要なエラー DB接続失敗、外部API呼び出し失敗
WARN 潜在的な問題、注意が必要な状況 非推奨APIの使用、リトライ発生
INFO アプリケーションの正常な動作記録 サービス開始/終了、重要な処理完了
DEBUG 開発時のデバッグ情報 メソッドの入出力、変数の値
TRACE 非常に詳細なトレース情報 ループ内の処理、低レベルの動作

パッケージ別ログレベル設定例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!-- アプリケーションコード -->
<logger name="com.example.myapp" level="DEBUG" />

<!-- Spring Framework -->
<logger name="org.springframework" level="INFO" />
<logger name="org.springframework.web" level="DEBUG" />

<!-- Hibernate / JPA -->
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.orm.jdbc.bind" level="TRACE" />

<!-- 外部ライブラリ(通常はWARN以上) -->
<logger name="org.apache" level="WARN" />
<logger name="com.zaxxer.hikari" level="WARN" />

実行環境での動作確認

ログ出力のテスト

以下のようなコントローラを作成して、各ログレベルの出力を確認できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.myapp.controller;

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/log-test")
public class LogTestController {
    
    private static final Logger log = LoggerFactory.getLogger(LogTestController.class);
    
    @GetMapping
    public String testLogging() {
        log.trace("TRACEレベルのログ");
        log.debug("DEBUGレベルのログ");
        log.info("INFOレベルのログ");
        log.warn("WARNレベルのログ");
        log.error("ERRORレベルのログ");
        
        return "ログ出力テスト完了";
    }
}

期待される出力結果

devプロファイルで実行した場合、コンソールに以下のような出力が表示されます。

2026-01-04 17:00:00.123 DEBUG [           main] c.e.myapp.controller.LogTestController   : DEBUGレベルのログ
2026-01-04 17:00:00.124 INFO  [           main] c.e.myapp.controller.LogTestController   : INFOレベルのログ
2026-01-04 17:00:00.125 WARN  [           main] c.e.myapp.controller.LogTestController   : WARNレベルのログ
2026-01-04 17:00:00.126 ERROR [           main] c.e.myapp.controller.LogTestController   : ERRORレベルのログ

トラブルシューティング

よくある問題と解決策

logback-spring.xmlが読み込まれない

logback.xmlが存在する場合、そちらが優先されます。logback-spring.xmlのみを使用してください。

springProfileタグが認識されない

logback.xmlでは<springProfile>は使用できません。ファイル名をlogback-spring.xmlに変更してください。

ログファイルが作成されない

ログ出力先ディレクトリの権限を確認してください。また、<file>タグで指定したパスが正しいか確認してください。

1
2
<!-- 環境変数でパスを指定する場合 -->
<property name="LOG_PATH" value="${LOG_PATH:-./logs}" />

まとめ

本記事では、Spring Boot REST APIにおけるLogbackを使用したログ設定について解説しました。主なポイントは以下の通りです。

  • logback-spring.xmlを使用することでSpring Boot独自の拡張機能を活用できる
  • Appenderの種類を理解し、用途に応じて適切に使い分ける
  • SizeAndTimeBasedRollingPolicyで本番環境に適したログローテーションを設定する
  • <springProfile>タグで開発環境と本番環境のログ設定を分離する
  • ログレベルを適切に設定し、効率的なデバッグと運用を実現する

適切なログ設定は、アプリケーションの品質向上と運用効率化に直結します。本記事の設定例を参考に、プロジェクトの要件に合わせたログ設定を構築してください。

参考リンク