Spring Boot 日志處理篇
標簽:
SpringBoot
本文简介
前篇侧重 Log4j2 的配置,本篇侧重统一日志处理的应用,以下包含 HTTP 请求的日志处理、Exception 异常日志处理。
HTTP 请求日志
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@Log4j2public 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}
Exception 异常日志
1、全局异常处理 ExceptionController.java
package com.anoyi.controller;import com.anoyi.bean.ResponseBean;import lombok.AllArgsConstructor;import lombok.extern.log4j.Log4j2;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice@Log4j2
@AllArgsConstructor
public class ExceptionController { /**
* 抛出错误前,打印错误日志
* **/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseBean handleException(Exception exception){ log.error(exception.getMessage(), exception); return ResponseBean.error(exception);
}
}
作者:Anoyi
链接:https://www.jianshu.com/p/c883b86c34fa
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦


