通常我們自定義一個Aspect用于記錄請求日志,方便問題排查。
主要記錄了如下信息:
代碼實現(xiàn)
import cn.hutool.core.util.StrUtil;import cn.hutool.json.JSONUtil;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;@Slf4j@Aspect@Componentpublic class WebLogAspect { private final String LOCALHOST_IPV4 = “127.0.0.1”; private final String LOCALHOST_IPV6 = “0:0:0:0:0:0:0:1”; // 切入點 @Pointcut(“execution(public * demo.controller..*(..)))”) public void pointCut() { } @Around(“pointCut()”) public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { // 開始處理時間 long startTime = System.currentTimeMillis(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 構建成一條長日志,避免并發(fā)下日志輸出錯亂 StringBuilder sb = new StringBuilder(300); // 日志參數(shù) List reqArgs = new ArrayList(); sb.append(“================ Start ================”); // 打印路由 sb.append(“===> {}: {}”); String requestMethod = request.getMethod(); reqArgs.add(requestMethod); reqArgs.add(request.getRequestURL().toString()); // IP sb.append(“===> IP: {}”); reqArgs.add(getClientIp(request)); // 打印調用 controller 的全路徑以及執(zhí)行方法 sb.append(“===> Class Method: {}.{}”); reqArgs.add(joinPoint.getSignature().getDeclaringTypeName()); reqArgs.add(joinPoint.getSignature().getName()); // 打印請求頭 Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { sb.append(“=== Headers === {}: {}”); String headerName = headerNames.nextElement(); reqArgs.add(headerName); reqArgs.add(StrUtil.join(“”, request.getHeader(headerName))); } // 打印請求入?yún)? sb.append(“===> request params: {}”); reqArgs.add(JSONUtil.toJsonStr(joinPoint.getArgs()));// List args = Arrays.asList(joinPoint.getArgs());// log.info(“Request Args : {}”, new Gson().toJson(args)); Object result = joinPoint.proceed();// // 打印出參// log.info(“Response Args : {}”, new Gson().toJson(result));// // 打印處理耗時 sb.append(StrUtil.format(“處理耗時: {} ms “, System.currentTimeMillis() – startTime)); sb.append(“================ End =================”); // 打印 log.info(sb.toString(), reqArgs.toArray()); return result; } // 獲取客戶端IP public String getClientIp(HttpServletRequest request) { String ipAddress = request.getHeader(“X-Forwarded-For”); if (StrUtil.isEmpty(ipAddress) || “unknown”.equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader(“Proxy-Client-IP”); } if (StrUtil.isEmpty(ipAddress) || “unknown”.equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader(“WL-Proxy-Client-IP”); } if (StrUtil.isEmpty(ipAddress) || “unknown”.equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if (LOCALHOST_IPV4.equals(ipAddress) || LOCALHOST_IPV6.equals(ipAddress)) { try { InetAddress inetAddress = InetAddress.getLocalHost(); ipAddress = inetAddress.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } } } if (!StrUtil.isEmpty(ipAddress) && ipAddress.length() > 15 && ipAddress.indexOf(“,”) > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(“,”)); } return ipAddress; }}