Spring Boot 日誌處理你還在用Logback?java
前篇側重 Log4j2 的配置,本篇側重統一日誌處理的應用,如下包含 HTTP 請求的日誌處理、Exception 異常日誌處理。web
imgspring
一、明確日誌記錄的內容緩存
示例:用戶、IP地址、Method、URI、請求參數、請求體併發
二、全局攔截 MDCFilter.javaapp
package com.anoyi.config.server; import lombok.extern.log4j.Log4j2; import org.slf4j.MDC; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ReadListener; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.*; /** * 攔截請求信息,添加到日誌 */ @Component @Log4j2 public class MDCFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { try { MDC.put("user", request.getRemoteUser()); String query = request.getQueryString() != null ? "?" + request.getQueryString() : ""; if (request.getMethod().equals(HttpMethod.POST.name())) { MultiReadHttpServletRequest multiReadHttpServletRequest = new MultiReadHttpServletRequest(request); log.info("IP:{}, Method:{}, URI:{} Body:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query, multiReadHttpServletRequest.getRequestBody()); chain.doFilter(multiReadHttpServletRequest, response); } else { log.info("IP:{}, Method:{}, URI:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query); chain.doFilter(request, response); } } finally { MDC.clear(); } } /** * HttpServletRequest 請求體多讀 */ class MultiReadHttpServletRequest extends HttpServletRequestWrapper { // 緩存 RequestBody private String requestBody; MultiReadHttpServletRequest(HttpServletRequest request) { super(request); requestBody = ""; try { StringBuilder stringBuilder = new StringBuilder(); InputStream inputStream = request.getInputStream(); byte[] bs = new byte[1024]; int len; while ((len = inputStream.read(bs)) != -1) { stringBuilder.append(new String(bs, 0, len)); } requestBody = stringBuilder.toString(); } catch (IOException e) { e.printStackTrace(); } } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes()); return new ServletInputStream() { public int read() throws IOException { return byteArrayInputStream.read(); } @Override public boolean isFinished() { return byteArrayInputStream.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { } }; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(this.getInputStream())); } String getRequestBody() { return requestBody.replaceAll("\n", ""); } } }
三、配置日誌 Patternide
logging: pattern: console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%15.15t] %-40.40c{1.} [%X{user}] : %m%n%xwEx"
說明: MDC.put("user", request.getRemoteUser()); => %X{user}
© 著做權歸做者全部,轉載或內容合做請聯繫做者微服務
● Spring Boot 定製 parent 快速構建應用ui
● Spring Boot 容器化部署 - Dockerthis
● Spring Boot 日誌處理你還在用Logback?
● 【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?
本文由博客一文多發平臺 OpenWrite 發佈!