ユーザの操作手順を追跡するために、IPアドレスをログ出力したいなんて話があると思います。
そんな要件のSpring Bootでの実装手順です。
#バージョン
Spring Boot:1.3.6
#参考
Spring Bootのログ設定を変更する
デフォルト設定の変更方法などが簡潔にまとめられています。
Logback 使い方メモ
ローテーションとか、欲しい情報がまとまっていてありがたいです。
logback マニュアル-第8章 診断コンテキスト
lobbackは和訳があるのですね。素晴らしい。。
http://logback.qos.ch/manual/index_ja.html
#フォルダ構成
LogSettingFilter.javaでIPアドレスの取得、logback.xmlで出力設定しています。
└── src
└── main
├── java
│ └── com
│ └── example
│ ├── AppConfig.java
│ ├── LogSettingFilter.java
│ ├── SampleController.java
│ └── SpringbootLogApplication.java
└── resources
└── logback.xml
#実装
logback.xmlを作成します。
spring-boot.jar配下のdefaults.xmlを読み込んでいます。
パターンの内容はLogback 使い方メモ-メッセージのパターンを指定するにあります。
%X{client} は後述の診断コンテキストで設定しているパラメータでIPアドレスの設定箇所になります。
ここではコンソール出力のみしています。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d %p %t %c %X{client} - %m%n</Pattern>
</layout>
</appender>
</configuration>
JavaEEのFilterを実装したクラスを作成し、MDC(診断コンテキスト)にIPアドレスを設定します。
MDCにはスレッドローカルで保存されます。
package com.example;
import org.slf4j.MDC;
import javax.servlet.*;
import java.io.IOException;
/**
* ログ出力用の診断コンテキストを設定するFilterクラス.
*/
public class LogSettingFilter implements Filter {
String CLIENT = "client";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 診断コンテキストを設定します.
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
MDC.put(CLIENT, servletRequest.getRemoteAddr());
filterChain.doFilter(servletRequest, servletResponse);
} finally {
MDC.remove(CLIENT);
}
}
@Override
public void destroy() {
}
}
上記で作成したFilterクラスを設定します。
package com.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
LogSettingFilter logSettingFilterFilter() {
LogSettingFilter filter = new LogSettingFilter();
return filter;
}
}
適当なコントローラを作成してログ出力してみます。
package com.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/web/sample")
public class SampleController {
private static Logger logger = LoggerFactory.getLogger(SampleController.class);
@RequestMapping(method = RequestMethod.GET)
public int logSample() {
logger.info("IPアドレス出力");
return 1;
}
}
こんな感じで出力されます。
2016-07-18 16:39:04,522 INFO http-nio-8080-exec-1 com.example.SampleController 0:0:0:0:0:0:0:1 - IPアドレス出力