|
|
@@ -0,0 +1,93 @@
|
|
|
+package work.baiyun.chronicdiseaseapp.filter;
|
|
|
+
|
|
|
+import jakarta.servlet.FilterChain;
|
|
|
+import jakarta.servlet.ServletException;
|
|
|
+import jakarta.servlet.http.HttpServletRequest;
|
|
|
+import jakarta.servlet.http.HttpServletResponse;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.slf4j.MDC;
|
|
|
+import org.springframework.core.Ordered;
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.filter.OncePerRequestFilter;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+@Order(Ordered.LOWEST_PRECEDENCE - 50)
|
|
|
+public class RequestLoggingFilter extends OncePerRequestFilter {
|
|
|
+
|
|
|
+ private static final long SLOW_REQUEST_MS = 3000L;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void doFilterInternal(HttpServletRequest request,
|
|
|
+ HttpServletResponse response,
|
|
|
+ FilterChain filterChain) throws ServletException, IOException {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // ensure traceId/requestId/spanId exist in MDC for this request
|
|
|
+ String traceId = MDC.get("traceId");
|
|
|
+ if (traceId == null || traceId.isEmpty()) {
|
|
|
+ String fromHeader = request.getHeader("X-Trace-Id");
|
|
|
+ traceId = (fromHeader == null || fromHeader.isEmpty()) ? UUID.randomUUID().toString() : fromHeader;
|
|
|
+ MDC.put("traceId", traceId);
|
|
|
+ request.setAttribute("traceId", traceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ String requestId = MDC.get("requestId");
|
|
|
+ if (requestId == null || requestId.isEmpty()) {
|
|
|
+ String fromHeader = request.getHeader("X-Request-Id");
|
|
|
+ requestId = (fromHeader == null || fromHeader.isEmpty()) ? UUID.randomUUID().toString() : fromHeader;
|
|
|
+ MDC.put("requestId", requestId);
|
|
|
+ request.setAttribute("requestId", requestId);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (log.isInfoEnabled()) {
|
|
|
+ log.info("▶▶ {} {} - {} [traceId:{}]", request.getMethod(), getRequestUri(request), getClientIp(request), traceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ filterChain.doFilter(request, response);
|
|
|
+
|
|
|
+ } finally {
|
|
|
+ long cost = System.currentTimeMillis() - start;
|
|
|
+ int status = response.getStatus();
|
|
|
+ if (log.isInfoEnabled()) {
|
|
|
+ log.info("◀◀ {} {} - {}ms [status:{}, traceId:{}]",
|
|
|
+ request.getMethod(), getRequestUriWithQuery(request), cost, status, traceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cost > SLOW_REQUEST_MS) {
|
|
|
+ log.warn("慢请求: {} {} 耗时: {}ms [status:{}, traceId:{}]", request.getMethod(), getRequestUriWithQuery(request), cost, status, traceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理 MDC 中的值(若不是由后续组件清理)
|
|
|
+ MDC.remove("requestId");
|
|
|
+ MDC.remove("traceId");
|
|
|
+ MDC.remove("spanId");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getRequestUri(HttpServletRequest request) {
|
|
|
+ return request.getRequestURI();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getRequestUriWithQuery(HttpServletRequest request) {
|
|
|
+ String qs = request.getQueryString();
|
|
|
+ if (qs == null || qs.isEmpty()) return request.getRequestURI();
|
|
|
+ return request.getRequestURI() + "?" + qs;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getClientIp(HttpServletRequest request) {
|
|
|
+ String ip = request.getHeader("X-Forwarded-For");
|
|
|
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getHeader("X-Real-IP");
|
|
|
+ }
|
|
|
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getRemoteAddr();
|
|
|
+ }
|
|
|
+ return ip;
|
|
|
+ }
|
|
|
+}
|