前篇
Spring Boot 日志处理你还在用 Logback?
本文简介
前篇侧重 Log4j2 的配置,本篇侧重统一日志处理的应用,以下包含 HTTP 请求的日志处理、Exception 异常日志处理。
HTTP 请求日志
img
1、明确日志记录的内容
示例:用户、IP 地址、Method、URI、请求参数、请求体
2、全局拦截 MDCFilter.java
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", "");
}
}
}
3、配置日志 Pattern
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 发布!