Spring Boot ログ出力

Spring BootのWEB画面上でlog4j2を利用してみた

今回は、log4j2という、log4jの後継でパフォーマンスが大幅に改善されたライブラリを利用してコンソールとファイルにログ出力を行ってみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring Bootの設定ファイルをapplication.propertiesからapplication.ymlに変更してみたこれまで、Spring Bootの設定ファイルとして「application.properties」を利用してきたが、YAML形式の設定...

サンプルプログラムの内容

今回のサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠のうち、「DemoInvocation.java」「log4j2.xml」「mybatis-config.xml」が新規で作成したプログラムで、他は変更したプログラムとなる。

build.gradleの内容は以下の通りで、log4j2とAOPを利用する設定を追加している。また、Spring Bootデフォルトのログ出力定義「Logback」を使わないよう、「spring-boot-starter-logging」を使わないような設定を追加している。

plugins {
	id 'org.springframework.boot' version '2.1.7.RELEASE'
	id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

configurations {
	//log4j2を利用するため、Spring BootデフォルトのLogbackを利用しないよう設定
	all*.exclude module : 'spring-boot-starter-logging'
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	compileOnly 'org.projectlombok:lombok:1.18.10'
	annotationProcessor 'org.projectlombok:lombok:1.18.10'
	compile files('lib/ojdbc6.jar')
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.1'
	compile group: 'org.springframework.data', name: 'spring-data-commons-core', version: '1.1.0.RELEASE'
	//log4j2を利用するための設定
	compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.12.1'
	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.12.1'
	//AOPを利用するための設定
	implementation 'org.springframework.boot:spring-boot-starter-aop'
}

次に、MyBatisのSQLログをlog4j2を使って出力できるよう、「mybatis-config.xml」を追加している。なお、「mybatis-config.xml」を読み込める設定は「application.yml」に追加している。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- log4j2.xmlを利用してSQLログを出力するための設定 -->
        <setting name="logImpl" value="LOG4J2"/>
    </settings>
</configuration>



さらに、「application.yml」の内容は以下の通り。「Logback」によるログ出力の定義を削除し、「mybatis-config.xml」を読み込む定義を追加している。

server:
  port: 8084
# DB接続情報
spring:
  datasource:
    url: jdbc:oracle:thin:@localhost:1521:xe
    username: USER01
    password: USER01
    driverClassName: oracle.jdbc.driver.OracleDriver
# mybatis定義ファイル
mybatis:
  config-location: classpath:/mybatis-config.xml
# 一覧画面で1ページに表示する行数
demo:
  list:
    pageSize: 2

また、「log4j2.xml」の内容は以下の通り。アプリケーションのログを、コンソールとログファイルに出力するよう設定している。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="OFF">
    <Appenders>
        <!-- コンソールログ出力設定 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
            </PatternLayout>
        </Console>
        <!-- ログファイル出力設定 -->
        <File name="LogFile" fileName="C:/work/logs/demo.log">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <!-- コンソールとファイルにログ出力をするための設定 -->
        <Logger name="com.example.demo" level="debug" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="LogFile"/>
        </Logger>
    </Loggers>
</Configuration>



さらに、Spring Boot起動後に、テスト用のログ出力をする処理を「DemoApplication.java」に追加している。

package com.example.demo;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@SpringBootApplication
public class DemoApplication implements WebMvcConfigurer {

	@Autowired
	private MessageSource messageSource;

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);

		//Log4j2でログ出力を行う
		Logger logger = LogManager.getLogger(DemoApplication.class);
		logger.debug("これはDEBUG(デバッグ)のテスト用ログです");
		logger.info("これはINFO(情報)のテスト用ログです");
		logger.warn("これはWARN(警告)のテスト用ログです");
		logger.error("これはERROR(エラー)のテスト用ログです。");
	}

	@Bean
	public LocalValidatorFactoryBean validator() {
		//Spring Bootデフォルトのエラーメッセージのプロパティファイルを
		//ValidationMessages.propertiesからmessages.propertiesに変更する
		LocalValidatorFactoryBean localValidatorFactoryBean 
                                              = new LocalValidatorFactoryBean();
		localValidatorFactoryBean.setValidationMessageSource(messageSource);
		return localValidatorFactoryBean;
	}

	@Override
	public org.springframework.validation.Validator getValidator() {
		return validator();
	}
}

また、コントローラクラスのpublicメソッド実行時に開始・終了ログを出力する設定を、AOPを利用して「DemoInvocation.java」に追加している。

package com.example.demo;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DemoInvocation {

    //ログ出力のためのクラス
    private Logger logger = LogManager.getLogger(DemoInvocation.class);

    /**
     * Beforeアノテーションにより、指定したメソッドの前に処理を追加する
     * Beforeアノテーションの引数には、
     * Pointcut式 execution(戻り値 パッケージ.クラス.メソッド(引数))を
     * 指定し、ここではControllerクラスの全メソッドの実行前にログ出力するようにしている
     *
     * @param jp 横断的な処理を挿入する場所
     */
    @Before("execution(public String com.example.demo.*Controller.*(..))")
    public void startLog(JoinPoint jp){
        //開始ログを出力
        String signature = jp.getSignature().toString();
        logger.info("開始ログ : " + signature);
    }

    /**
     * Afterアノテーションにより、指定したメソッドの前に処理を追加する
     * Afterアノテーションの引数には、Pointcut式を指定
     *
     * @param jp 横断的な処理を挿入する場所
     */
    @After("execution(public String com.example.demo.*Controller.*(..))")
    public void endLog(JoinPoint jp){
        //終了ログを出力
        String signature = jp.getSignature().toString();
        logger.info("終了ログ : " + signature);
    }

}

なお、AOPについては、以下の記事を参照のこと。

Spring BootでAOPを利用してみたSpringフレームワークの基本として、AOP(Aspect Oriented Programming)という概念がある。 AOP...

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-log4j2/demo

サンプルプログラムの実行結果

Spring Bootアプリケーションを起動すると、以下のように、コンソールとログファイルに「DemoApplication.java」に追加したログが出力されることが確認できる。

<コンソール>
コンソールログ(起動時)

<ログファイル>
※log4j2.xmlの「LogFile」で指定したfileName「C:/work/logs/demo.log」にログが出力される。
ファイルログ(起動時)

次に、「http:// (ホスト名):(ポート番号)」とアクセスし、以下の画面動作を行う。
画面動作1

画面動作2

この場合のコンソールとログファイルの内容は以下の通りで、「DemoInvocation.java」で定義したログとSQLログが出力されることが確認できる。

<コンソール>
コンソールログ(画面動作時)

<ログファイル>
※log4j2.xmlの「LogFile」で指定したfileName「C:/work/logs/demo.log」にログが出力される。
ファイルログ(画面動作時)

要点まとめ

  • log4j2を利用するには、build.gradleにlog4j-apiとlog4j-coreのver2.x.xのライブラリを追加し、Spring BootデフォルトのLogbackを利用しない設定を追加する。
  • log4j2のログ出力定義は、log4j2.xmlで行う。
  • log4j2でSQLログを出力するには、mybatis-config.xmlでlogImplの設定値をLOG4J2に設定する。