Spring Boot 日志处理你还在用Logback?
前篇侧重 Log4j2 的配置,本篇侧重统一日志处理的应用,以下包含 HTTP 请求的日志处理、Exception 异常日志处理。
img
示例:用户、IP地址、Method、URI、请求参数、请求体
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", ""); } } }
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 快速构建应用
● Spring Boot 容器化部署 - Docker
● SpringBot中教你手把手配置 https
● Spring Boot 日志处理你还在用Logback?
● 【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?
● Spring Boot 新一代监控你该这么玩
● Spring Boot 异常处理
● Spring Boot 配置 - 配置信息加密
● 拒绝黑盒应用-Spring Boot 应用可视化监控
● 并发Bug之源有三,请睁大眼睛看清它们
本文由博客一文多发平台 OpenWrite 发布!