SpringBoot正确打日志的姿势

编程

前篇

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("

", "");

}

}

}

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 发布!

以上是 SpringBoot正确打日志的姿势 的全部内容, 来源链接: utcz.com/z/510584.html

回到顶部