本文简介

前篇侧重 Log4j2 的配置,本篇侧重统一日志处理的应用,以下包含 HTTP 请求的日志处理、Exception 异常日志处理。

HTTP 请求日志

SpringBoot正确打日志的姿势_SpringBootimg

1、明确日志记录的内容

示例:用户、IP地址、Method、URI、请求参数、请求体

2、全局拦截 MDCFilter.java

拦截器拦截请求体来获取记录内容并进行日志输出,直接上代码:

  1package com.anoyi.config.server;
  2
  3import lombok.extern.log4j.Log4j2;
  4import org.slf4j.MDC;
  5import org.springframework.http.HttpMethod;
  6import org.springframework.stereotype.Component;
  7import org.springframework.web.filter.OncePerRequestFilter;
  8
  9import javax.servlet.FilterChain;
 10import javax.servlet.ReadListener;
 11import javax.servlet.ServletException;
 12import javax.servlet.ServletInputStream;
 13import javax.servlet.http.HttpServletRequest;
 14import javax.servlet.http.HttpServletRequestWrapper;
 15import javax.servlet.http.HttpServletResponse;
 16import java.io.*;
 17
 18/**
 19 * 拦截请求信息,添加到日志
 20 */
 21@Component
 22@Log4j2
 23public class MDCFilter extends OncePerRequestFilter {
 24
 25    @Override
 26    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
 27        try {
 28            MDC.put("user", request.getRemoteUser());
 29            String query = request.getQueryString() != null ? "?" + request.getQueryString() : "";
 30            if (request.getMethod().equals(HttpMethod.POST.name())) {
 31                MultiReadHttpServletRequest multiReadHttpServletRequest = new MultiReadHttpServletRequest(request);
 32                log.info("IP:{}, Method:{}, URI:{} Body:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query, multiReadHttpServletRequest.getRequestBody());
 33                chain.doFilter(multiReadHttpServletRequest, response);
 34            } else {
 35                log.info("IP:{}, Method:{}, URI:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query);
 36                chain.doFilter(request, response);
 37            }
 38        } finally {
 39            MDC.clear();
 40        }
 41    }
 42
 43    /**
 44     * HttpServletRequest 请求体多读
 45     */
 46    class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
 47
 48        // 缓存 RequestBody
 49        private String requestBody;
 50
 51        MultiReadHttpServletRequest(HttpServletRequest request) {
 52            super(request);
 53            requestBody = "";
 54            try {
 55                StringBuilder stringBuilder = new StringBuilder();
 56                InputStream inputStream = request.getInputStream();
 57                byte[] bs = new byte[1024];
 58                int len;
 59                while ((len = inputStream.read(bs)) != -1) {
 60                    stringBuilder.append(new String(bs, 0, len));
 61                }
 62                requestBody = stringBuilder.toString();
 63            } catch (IOException e) {
 64                e.printStackTrace();
 65            }
 66        }
 67
 68        @Override
 69        public ServletInputStream getInputStream() throws IOException {
 70            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());
 71
 72            return new ServletInputStream() {
 73                public int read() throws IOException {
 74                    return byteArrayInputStream.read();
 75                }
 76
 77                @Override
 78                public boolean isFinished() {
 79                    return byteArrayInputStream.available() == 0;
 80                }
 81
 82                @Override
 83                public boolean isReady() {
 84                    return true;
 85                }
 86
 87                @Override
 88                public void setReadListener(ReadListener readListener) {
 89
 90                }
 91            };
 92        }
 93
 94        @Override
 95        public BufferedReader getReader() throws IOException {
 96            return new BufferedReader(new InputStreamReader(this.getInputStream()));
 97        }
 98
 99        String getRequestBody() {
100            return requestBody.replaceAll("\n", "");
101        }
102    }
103
104}

3、配置日志 Pattern

1logging:
2  pattern:
3    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}

© 著作权归作者所有,转载或内容合作请联系作者