package com.yaoyanshe.masterdata.framework.filter;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
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.aspectj.lang.reflect.CodeSignature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* -- Created by IntelliJ IDEA.
* -- REMARK: 统一请求报文输出、执行时间监控
* -- User: tanwei
* -- Date: 2020/12/21
* -- Time: 1:19 下午
* --
*/
@Slf4j
@Aspect
@Configuration
@AllArgsConstructor
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class ResponseLogAspect {
@Resource
private HttpServletRequest request;
/**
* 匹配controller层的方法
*/
@Pointcut(value = "(execution(* com.yaoyanshe.masterdata.controller..*.controller.*.*(..)))")
private void controllerPointcut() {
}
@Around(value = "controllerPointcut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
String requestUri = Objects.requireNonNull(request).getRequestURI();
String requestMethod = request.getMethod();
// 构建成一条长 日志,避免并发下日志错乱
StringBuilder beforeReqLog = new StringBuilder(300);
// 日志参数
List<Object> beforeReqArgs = new ArrayList<>();
beforeReqLog.append("\n\n================ Request Start ================\n");
// 打印路由
beforeReqLog.append("===> {}: {}");
beforeReqArgs.add(requestMethod);
beforeReqArgs.add(requestUri);
Map<String, Object> paraMap = getNameAndValue(point);
// 请求参数
if (paraMap.isEmpty()) {
beforeReqLog.append("\n");
} else {
beforeReqLog.append(" Parameters: {}\n");
beforeReqArgs.add(JSONObject.toJSON(paraMap));
}
// 打印请求头
Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String headerName = headers.nextElement();
String headerValue = request.getHeader(headerName);
beforeReqLog.append("===Headers=== {} : {}\n");
beforeReqArgs.add(headerName);
beforeReqArgs.add(headerValue);
}
beforeReqLog.append("================ Request End ================\n");
// 打印执行时间
long startNs = System.nanoTime();
log.info(beforeReqLog.toString(), beforeReqArgs.toArray());
// aop 执行后的日志
StringBuilder afterReqLog = new StringBuilder(200);
// 日志参数
List<Object> afterReqArgs = new ArrayList<>();
afterReqLog.append("\n\n================ Response Start ===============\n");
try {
Object result = point.proceed();
// 打印返回结构体
afterReqLog.append("===Result=== {}\n");
afterReqArgs.add(JSONObject.toJSON(result));
return result;
} finally {
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
afterReqLog.append("<=== {}: {} ({} ms)\n");
afterReqArgs.add(requestMethod);
afterReqArgs.add(requestUri);
afterReqArgs.add(tookMs);
afterReqLog.append("================ Response End ===============\n");
log.info(afterReqLog.toString(), afterReqArgs.toArray());
}
}
/**
* 获取参数Map集合
*/
private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
Map<String, Object> param = new HashMap<>(8);
Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for (int i = 0; i < paramNames.length; i++) {
param.put(paramNames[i], paramValues[i]);
}
if (log.isDebugEnabled()) {
log.debug("param: {}", JSONObject.toJSONString(param));
}
return param;
}
}
controller拦截请求报文统一输出报文
最新推荐文章于 2024-03-02 15:21:45 发布