Spring Bootアプリケーションを開発していると、ログ出力の設定が必要になりますよね。開発中はデバッグ情報を詳しく見たいけど、本番環境では必要なログだけをファイルに保存したい。この記事では、Spring Boot 3.x系を対象に、ログ設定を基礎から実践まで段階的に解説します。
Spring Bootのデフォルトログ動作
コードからログを出力する方法(LoggerFactory / @Slf4j)
設定の前に、まずアプリケーションのコードからログを出力する基本を押さえておきましょう。標準的な方法は、SLF4Jの LoggerFactory からロガーを取得することです。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class OrderService {
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public void createOrder(String orderId) {
log.info("注文を受け付けました: orderId={}", orderId);
log.debug("注文処理の詳細情報: {}", orderId);
}
}
メッセージ内の {} はプレースホルダーで、引数の値が埋め込まれます。文字列連結("orderId=" + orderId)と違い、そのログレベルが無効な場合には文字列の生成コスト自体が発生しないため、必ずプレースホルダー形式を使いましょう。
なお、本番コードでの System.out.println は避けてください。ログレベルによる出力制御ができず、タイムスタンプやスレッド名も付かず、ファイル出力やローテーションの対象にもなりません。ロガー経由にしておけば、この記事で解説する設定がすべてそのまま適用されます。
Lombokを導入しているプロジェクトなら、@Slf4j アノテーションでロガー宣言を省略できます。
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class OrderService {
public void createOrder(String orderId) {
log.info("注文を受け付けました: orderId={}", orderId);
}
}
@Slf4j を付けるだけで log という名前のロガーフィールドが自動生成されます。実務のSpring Bootプロジェクトではこちらの書き方が主流です。
ログレベル別のメソッドは重要度の低い順に trace / debug / info / warn / error の5つです。使い分けの目安は次の通りです。
- ERROR: 即時対応が必要な障害(例外の捕捉、外部サービス接続失敗)
- WARN: すぐには壊れないが注意が必要な状態(リトライ発生、非推奨API使用)
- INFO: 業務上の重要イベント(注文受付、バッチ開始・終了)
- DEBUG: 開発時の調査に使う詳細情報(パラメータの中身、分岐の通過)
- TRACE: さらに細かい実行トレース(通常は使わない)
例外をログに残すときは、例外オブジェクトを最後の引数に渡すとスタックトレースが出力されます。
try {
externalApi.call();
} catch (ApiException e) {
log.error("外部API呼び出しに失敗しました: orderId={}", orderId, e);
}
Spring Bootは特別な設定をしなくても、起動時からログを出力してくれます。これはSpring Bootが SLF4J をログファサードとして、Logback を実装として標準採用しているためです。
spring-boot-starter-web などのスターターを使っていれば、spring-boot-starter-logging が自動的に依存関係に含まれます。デフォルトではINFOレベル以上のログがコンソールに出力される設定です。
実装をLog4j2に切り替えることもできます。spring-boot-starter-logging を依存関係から除外して spring-boot-starter-log4j2 を追加すれば、SLF4JのAPIを使っている限りアプリケーションコードは変更不要です。ただしLogbackで困る場面はほとんどないため、既存プロジェクトでLog4j2を採用している等の事情がなければ標準のままで問題ありません。
application.propertiesでログレベルを変更する
まずは一番簡単な方法から始めましょう。application.properties を使えば、XMLファイルを作らなくてもログレベルを変更できます。
# アプリケーション全体のログレベル
logging.level.root=INFO
# 特定パッケージのログレベル
logging.level.com.example.myapp=DEBUG
logging.level.org.springframework.web=WARN
logging.level.root でアプリケーション全体のデフォルトレベルを設定し、logging.level.パッケージ名 で特定パッケージだけ細かく調整できます。開発中は自分のパッケージだけDEBUGにして、Springフレームワーク自体のログは抑える、といった使い方が便利です。
logback-spring.xmlの基本構造
より高度な設定をするには、Logbackの設定ファイルを作ります。src/main/resources/logback-spring.xml というファイル名で配置しましょう。
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
Logback設定ファイルは主に3つの要素で構成されます。
- appender はログの出力先と形式を定義
- logger は特定パッケージの設定
- root は全体のデフォルト設定
ファイル名を logback.xml ではなく logback-spring.xml にすることで、Spring Boot固有の機能が使えるようになります。たとえば springProfile タグによる環境別設定や、springProperty タグによる application.properties で定義したプロパティの参照は、logback.xml では動作しません。logback.xml はSpring Bootの初期化より前にLogbackが直接読み込むためです。Spring Bootプロジェクトでは logback-spring.xml に統一しておくのが安全です。
コンソールアペンダーのカスタマイズ
コンソール出力のフォーマットは pattern で自由に変更できます。よく使うパターンをいくつか紹介します。
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{40}) - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
%d{...}はタイムスタンプの形式%threadはスレッド名%-5levelはログレベル(-は左詰めを意味し、5文字分の幅を確保)%logger{40}はロガー名(最大40文字)%msgはログメッセージ%nは改行%highlight,%cyanは色付け(開発環境で見やすい)
色付き出力は開発環境では便利ですが、本番環境やログファイルではANSIエスケープシーケンスが不要なので、環境別に設定を分けると良いでしょう。
ファイル出力とログローテーション
本番環境ではログをファイルに保存したいですよね。ログファイルが際限なく大きくなると困るので、実務では最初から RollingFileAppender を使ってローテーション設定をしておきましょう。
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/application-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
maxFileSizeは1ファイルの最大サイズ(10MBを超えたら新しいファイルに切り替え)maxHistoryは保持する日数(30日分保存)totalSizeCapは全ログファイルの合計サイズ上限(1GBまで)
ファイル名に .gz を付けると、古いログファイルが自動的にgzip圧縮されます。
重要 な注意点として、Logbackは logs ディレクトリを自動作成しません。存在しないディレクトリを指定すると起動時にエラーになるので、事前に mkdir logs で作成しておくか、絶対パスで確実に存在するディレクトリを指定してください。
環境別にログ設定を切り替える
Spring Boot 3.4以降の構造化ログ(JSON出力)
Spring Boot 3.4からは、Logbackの設定ファイルを書かなくても 構造化ログ(JSON形式) をネイティブにサポートするようになりました。application.properties に1行追加するだけです。
# コンソール出力をElastic Common Schema形式のJSONにする
logging.structured.format.console=ecs
# ファイル出力を構造化する場合
logging.structured.format.file=ecs
対応フォーマットは ecs(Elastic Common Schema)、logstash、gelf(Graylog、3.5以降)の3種類です。出力は次のようなJSONになります。
{"@timestamp":"2026-08-29T10:15:30.123Z","log.level":"INFO","message":"注文を受け付けました: orderId=A123","process.thread.name":"http-nio-8080-exec-1","log.logger":"com.example.myapp.OrderService"}
ElasticsearchやCloudWatch Logs、Lokiなどのログ基盤はJSONを構造のまま取り込めるため、orderId のようなフィールドでの検索・集計が格段に楽になります。KubernetesなどのコンテナでSpring Bootを運用する場合は、ファイル出力+ローテーションよりも「JSONで標準出力に出して収集基盤に任せる」構成が第一候補です。コンテナ運用の全体像はSpring BootアプリをKubernetesにデプロイする記事を参照してください。
なお、この機能はSpring Boot 3.4以降でのみ使えます。それ以前のバージョンでJSONログが必要な場合は、従来通り logstash-logback-encoder ライブラリを logback-spring.xml に組み込む方法を使いましょう。詳細はSpring Boot公式ドキュメントのStructured Loggingの章にまとまっています。
Spring Bootの Profile機能 を使えば、開発環境と本番環境で異なるログ設定を適用できます。環境別設定の詳細はProfileの記事も参照してください。
<configuration>
<springProfile name="dev">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{40}) - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<springProfile name="prod">
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/application-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>
application.properties で spring.profiles.active=prod と指定すれば、本番用の設定が適用されます。開発環境では詳細なDEBUGログをコンソールに表示し、本番環境ではINFOレベル以上をファイルに保存、という運用が簡単に実現できますね。
なお、コンテナ環境(DockerやKubernetesなど)では、ログファイルではなく標準出力にログを出力して外部のログ収集システムに流す運用も一般的です。環境に応じて選択しましょう。
実践的な完全設定例
MDCでリクエストIDをログに自動付与する
複数のリクエストが並行して処理される本番環境では、「このログはどのリクエストのものか」を追跡できることが重要です。そこで使うのが MDC(Mapped Diagnostic Context)です。スレッドローカルに値を保存しておくと、そのスレッドから出力されるすべてのログに自動で値を付与できます。
サーブレットフィルタでリクエストごとにIDを発行する例です。
@Component
public class RequestIdFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestId = UUID.randomUUID().toString().substring(0, 8);
MDC.put("requestId", requestId);
try {
filterChain.doFilter(request, response);
} finally {
MDC.remove("requestId");
}
}
}
ログパターンに %X{キー名} を追加すると、MDCの値が出力されます。
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{requestId}] %-5level %logger{36} - %msg%n</pattern>
finally ブロックでの MDC.remove() を忘れないでください。アプリケーションサーバーはスレッドを使い回すため、削除しないと別のリクエストに前の値が漏れてしまいます。
MDCを例外ハンドリングと組み合わせてtraceIDによる問い合わせ追跡を実現する実装は、GlobalExceptionHandlerを本番運用向けに実装する記事で詳しく解説しています。
最後に、実務で使える完全な設定例を紹介します。開発環境と本番環境の両方に対応し、パッケージごとのログレベル調整も含めています。
<configuration>
<property name="LOG_PATH" value="logs" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/application.log</file>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/application-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
<logger name="com.example.myapp" level="DEBUG" />
</springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<logger name="org.springframework" level="WARN" />
<logger name="com.example.myapp" level="INFO" />
</springProfile>
</configuration>
<property> タグを使って変数を定義すると、設定の重複を減らせて保守性が上がります。
リクエストIDやユーザーIDなど、ログに付加情報を自動で含めたい場合は MDC(Mapped Diagnostic Context)という仕組みが便利です。詳細は別記事で扱いますが、スレッドローカルに値を保存してログ出力時に自動付与できる機能として覚えておくと良いでしょう。
ログ設定のトラブルシューティング
ログ設定でよくあるトラブルと対処法をまとめておきます。
- ログが出力されない →
logback-spring.xmlの構文エラーをチェック。起動時のコンソールにLogback configuration errorが出ていないか、ファイルがsrc/main/resources/logback-spring.xmlに置かれているか確認 - ファイルに書き込めない → ログディレクトリが存在するか、書き込み権限があるか確認
- ログレベルが反映されない → 設定の優先順位を確認。基本的には
logback-spring.xml>application.properties> デフォルト設定の順で優先される。ロガー名(パッケージ名)のスペルミスもよくある原因
本番環境でのログ運用
実務でログを運用する際のポイントをいくつか押さえておきましょう。
本番環境では INFO 以上、開発環境では DEBUG に設定するのが基本です。DEBUGやTRACEはログ量が多すぎて、ディスク容量やパフォーマンスに悪影響を与えます。
ローテーション設定は必須と考えてください。ログファイルが際限なく大きくなると、ディスクを圧迫してアプリケーションが停止する原因になります。
個人情報や機密情報(パスワード、トークン、クレジットカード番号など)は絶対にログに残してはいけません。デバッグ時にうっかり出力してしまわないよう注意しましょう。
まとめ
この記事では、Spring Bootのログ設定を基礎から実践まで段階的に解説しました。
application.properties での簡単なログレベル変更から始めて、logback-spring.xml を使った本格的な設定まで、実務で必要な知識を一通りカバーしています。環境別の設定切り替えやログローテーションも含めて、本番環境で運用できるレベルの設定が実装できるようになったはずです。
ログ設定と組み合わせて、Spring Boot Actuatorを使えばアプリケーションの監視もできるようになります。実務での運用を見据えて、ぜひ試してみてくださいね。
関連記事
ログ設定とあわせて押さえておきたい、本番運用に関わる記事です。
- Spring BootのGlobalExceptionHandlerを本番運用向けに実装する - 例外のログ設計とMDCによるtraceID付与
- Spring BootアプリをKubernetesにデプロイする方法 - コンテナ環境でのログ収集を含む運用構成
- Spring Bootのグレースフルシャットダウンとゼロダウンタイムデプロイを実現する方法 - デプロイ時のログとリクエスト処理の落とし穴