1. 程式人生 > 程式設計 >SpringBoot正確打日誌的姿勢

SpringBoot正確打日誌的姿勢

前篇

Spring Boot 日誌處理你還在用Logback?

本文簡介

前篇側重 Log4j2 的配置,本篇側重統一日誌處理的應用,以下包含 HTTP 請求的日誌處理、Exception 異常日誌處理。

HTTP 請求日誌

imgimg

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:{},URI:{}",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,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"複製程式碼

txt

說明: MDC.put("user",request.getRemoteUser()); => %X{user}

© 著作權歸作者所有,轉載或內容合作請聯絡作者

img

Spring Boot 定製 parent 快速構建應用

Spring Boot 容器化部署 - Docker

SpringBot中教你手把手配置 https

Spring Boot 日誌處理你還在用Logback?

【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?

Spring Boot 新一代監控你該這麼玩

Spring Boot 異常處理

Spring Boot 配置 - 配置資訊加密

拒絕黑盒應用-Spring Boot 應用視覺化監控

併發Bug之源有三,請睜大眼睛看清它們

img

本文由部落格一文多發平臺 OpenWrite 釋出!