项目AOP处理请求日志
单个请求
功能描述:在进入请求前打印日志及参数,请求执行完成后打印响应结果。
为要打印日志的请求定义注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
/**
* 请求名称
*
* @return /
*/
String value() default "";
}
使用AOP解析每个使用了该注解的请求:
@Slf4j
@Aspect
@Component
public class RequestLogResolver {
@Pointcut("@annotation(com.xxx.xxx.common.aspect.RequestLog)")
private void pointCut() {
}
@Around("pointCut()")
public Object beforeRequestLog(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
Annotation[] annotations = method.getAnnotations();
RequestLog requestLogAnnotation = null;
for (Annotation annotation : annotations) {
if (annotation.annotationType().getSimpleName().equals(RequestLog.class.getSimpleName())) {
requestLogAnnotation = (RequestLog) annotation;
break;
}
}
String requestName = "";
if (requestLogAnnotation != null) {
requestName = requestLogAnnotation.value();
}
StringBuilder parameterPlaceHolder = new StringBuilder();
Object[] args = pjp.getArgs();
int length = args.length;
if (length > 0) {
for (int i = 0; i < length; i++) {
parameterPlaceHolder.append("参数 ").append(i + 1).append(":{} ");
}
log.info("开始执行【" + requestName + "】请求,请求参数为:" + parameterPlaceHolder, args);
} else {
log.info("开始执行【" + requestName + "】请求,请求参数为空");
}
Object result = pjp.proceed(args);
log.info("结束执行【" + requestName + "】请求,请求结果为:{}", result);
return result;
}
}
微服务关联请求
(下面代码是基于Feign写的,服务间调用采用其它方式的可以参考下面的写法)
功能描述:在进入请求前打印请求参数,如果整个请求内有访问其它服务,其它服务会基于同一个请求ID,打印日志,请求结束后打印响应结果。服务内所有请求都有同一个请求ID,便于定位问题。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
/**
* 请求名称
*
* @return /
*/
String value() default "";
/**
* 是否继承RequestId
* 默认继承
*
* @return /
*/
boolean extendsRequestId() default true;
}
@Slf4j
@Aspect
@Component
public class RequestLogResolver {
public static final String REQUEST_LOG_ID_NAME = "NEW_COIN_REQUEST_LOG_ID";
@Pointcut("@annotation(com.xxx.common.web.aspect.RequestLog)")
private void pointCut() {
}
@Around("pointCut()")
public Object beforeRequestLog(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
Annotation[] annotations = method.getAnnotations();
RequestLog requestLogAnnotation = null;
for (Annotation annotation : annotations) {
if (annotation.annotationType().getSimpleName().equals(RequestLog.class.getSimpleName())) {
requestLogAnnotation = (RequestLog) annotation;
break;
}
}
String requestName = "";
boolean extendsRequestId = true;
if (requestLogAnnotation != null) {
requestName = requestLogAnnotation.value();
extendsRequestId = requestLogAnnotation.extendsRequestId();
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String requestId = null;
if (extendsRequestId) {
// 继承RequestId,从Header中取值
requestId = request.getHeader(REQUEST_LOG_ID_NAME);
}
if (requestId == null) {
requestId = "REQUEST_" + UUIDUtils.uuid();
}
HttpSession session = request.getSession();
session.setAttribute(REQUEST_LOG_ID_NAME, requestId);
StringBuilder parameterPlaceHolder = new StringBuilder();
Object[] args = pjp.getArgs();
int length = args.length;
if (length > 0) {
for (int i = 0; i < length; i++) {
parameterPlaceHolder.append("参数 ").append(i + 1).append(":{} ");
}
log.info("开始执行【" + requestName + "】请求【{}】,请求参数为:" + parameterPlaceHolder, requestId, args);
} else {
log.info("开始执行【" + requestName + "】请求【{}】,请求参数为空");
}
Object result = pjp.proceed(args);
log.info("结束执行【" + requestName + "】请求【{}】,请求结果为:{}", requestId, result);
// 请求结束后,清除请求ID
session.removeAttribute(REQUEST_LOG_ID_NAME);
return result;
}
}
@Slf4j
@Configuration
public class FeignConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpSession session = attributes.getRequest().getSession();
String requestId = (String) session.getAttribute(RequestLogResolver.REQUEST_LOG_ID_NAME);
if (StringUtils.isNotEmpty(requestId)) {
log.debug("Feign调用设置请求ID,{}", requestId);
requestTemplate.header(RequestLogResolver.REQUEST_LOG_ID_NAME, requestId);
}
}
}