ServletFilter
-
Java EE の一部であり、セキュリティ、ロギング、圧縮などのサブレットレベルでの作業に適している。
-
すべてのログを残す例
import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.UUID; @Slf4j public class LogFilter implements Filter { // Filter 인터페이스를 구현한다. @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("log filter init"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info("log filter doFilter"); // Servlet Request はHTTP リクエストでない場合まで考慮して作ったインターフェースなので、 // Http Servlet Request でダウンキャスティングすればよい。 HttpServletRequest httpServletRequest = (HttpServletRequest) request; String requestURI = httpServletRequest.getRequestURI(); String uuid = UUID.randomUUID().toString(); try { log.info("REQUEST [{}][{}]", uuid, requestURI); // 次のfilter呼び出し、なければservlet呼び出し chain.doFilter(request, response); } catch (Exception e) { throw e; } finally { log.info("RESPONSE [{}][{}]", uuid, requestURI); } } @Override public void destroy() { log.info("log filter destroy"); } } 2024-01-02 22:06:19.559 INFO [restartedMain] [c.eunaa2934.acshop.web.filter.LogFilteƒr] - log filter init 2024-01-02 22:06:22.184 INFO [http-nio-8080-exec-8] [c.eunaa2934.acshop.web.filter.LogFilter] - REQUEST [0ea1e015-8728-494d-8d42-b928c27a1aba][/css/common/common.css] 2024-01-02 22:06:22.184 INFO [http-nio-8080-exec-9] [c.eunaa2934.acshop.web.filter.LogFilter] - REQUEST [f9a2e173-faf7-4ecd-96bd-e15b1eabcb02][/images/favicon.ico] 2024-01-02 22:06:22.186 INFO [http-nio-8080-exec-8] [c.eunaa2934.acshop.web.filter.LogFilter] - RESPONSE [0ea1e015-8728-494d-8d42-b928c27a1aba][/css/common/common.css] 2024-01-02 22:06:22.186 INFO [http-nio-8080-exec-9] [c.eunaa2934.acshop.web.filter.LogFilter] - RESPONSE [f9a2e173-faf7-4ecd-96bd-e15b1eabcb02][/images/favicon.ico] 2024-01-02 22:15:47.525 INFO [SpringApplicationShutdownHook] [c.eunaa2934.acshop.web.filter.LogFilter] - log filter destroy
MDC
- Mapped Diagnostic Contexts
- Multiスレッドの場合のように、同時に要請が複数ある時、要請ごとに固有のIDを付与して区分できるように提供されるmapである。
- Thread Localに区別できるキー値を保存して、Threadが存在する間、引き続き使用できるようにする。
application.properties logging.config=classpath:logback.xml
詳しくはLogging参考 <?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds"> ... <property name="LOG_PATTERN" value="[request_id=%X{request_id}] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%logger{40}] - %msg%n"/> ... </configuration>
import org.slf4j.MDC; @Slf4j public class LogFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info("log filter doFilter"); HttpServletRequest httpServletRequest = (HttpServletRequest) request; String requestURI = httpServletRequest.getRequestURI(); String uuid = UUID.randomUUID().toString(); try { // request_id枠を通じて要請ごとに固有のIDを付与して区分できるようにする。 MDC.put("request_id", uuid); log.info("REQUEST [{}]", requestURI); // 次のfilter呼び出し、なければservlet呼び出し chain.doFilter(request, response); // 要求が完了したときにクリアをしてくれないと、他の要求がそのスレッドを再利用するときに // 以前のデータが残っている可能性がある。 MDC.clear(); } catch (Exception e) { throw e; } finally { log.info("RESPONSE [{}]", requestURI); } } } // [request_id=75cbd951-7d1e-412b-adb8-66ebcf669c14] 2024-01-19 21:28:16.046 INFO [http-nio-8080-exec-2] [c.eunaa2934.acshop.web.filter.LogFilter] - REQUEST [/images/favicon.ico]