背景
在之前的项目中,每次想加调试日志,或者打印请求的时候都需要在类上增加一句
private static Logger log = LoggerFactory.getLogger(xxx.class);
后面写多了之后总觉得很麻烦的,就想能不能使用aop切面的方式来增加日志。废话不多说,开干。
引入版本
<!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
自定义注解
/**
* 接受外来服务请求的日志注解
* 记录请求和对应的返回值
*
* @author dzp
* @since 2020/9/2
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface RequestLog {
/**
* 是否记录请求参数
*/
boolean logParameters() default true;
/**
* 是否记录请求日志
*/
boolean logRequest() default true;
/**
* 是否记录返回值
*/
boolean logReturn() default false;
/**
* 是否以debug形式记录
*/
boolean isDebug() default false;
/**
* 日志类型
*/
LogNameEnum logName() default LogNameEnum.MEDICAL_APP;
}
日志类型枚举
/**
* 日志类型
*
* @author dzp
* @since 2020/12/6
*/
@Getter
public enum LogNameEnum {
/**
* 系统日志
*/
MEDICAL_APP(LoggerFactory.getLogger("medical_app"));
LogNameEnum(final Logger logger) {
this.logger = logger;
}
private final Logger logger;
}
常量类
public class LogConfig {
public enum LogType {
/**
* 请求日志
*/
HTTP,
}
/**
* http 请求url和参数
*/
public static final String HTTP_REQUEST_URL_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> url【%s】param:【%s】";
/**
* http 请求url
*/
public static final String HTTP_REQUEST_URL_PARAM_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> url【%s】";
/**
* http 响应
*/
public static final String HTTP_RESPONSE_RESULT_LOG = "%s ----> " + LogType.HTTP.toString() + " --------> return:【%s】";
}
aop切面
/**
* 用来记录相关日志
*
* @author dzp
* @since 2020/9/2
*/
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestLogAspect {
@Pointcut("within(@com.medical.app.aop.annotations.RequestLog *)")
public void withRequestLogAnnotation() {
}
@Around("withRequestLogAnnotation()")
public Object requestLogHandle(ProceedingJoinPoint pjp) throws Throwable {
//尝试获取当前方法的类名和方法名
MethodSignature signature = (MethodSignature) pjp.getSignature();
RequestLog requestLog = signature.getMethod().getAnnotation(RequestLog.class);
if (requestLog == null) {
requestLog = signature.getMethod().getDeclaringClass().getAnnotation(RequestLog.class);
}
//对于Web项目我们可以从上下文中获取到额外的一些信息来丰富我们的日志
String url = "";
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
url = request.getRequestURL().toString();
}
long timestamp = System.currentTimeMillis();
//实现的是入参的日志输出
if (requestLog.logParameters() && requestLog.logRequest()) {
if (pjp.getArgs() != null && pjp.getArgs().length > 0) {
Object arg = pjp.getArgs()[0];
if(arg instanceof MultipartFile) {
arg=((MultipartFile) arg).getName();
}
if (requestLog.isDebug()) {
requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_REQUEST_URL_LOG, timestamp, url, JSON.toJSONString(arg)));
} else {
requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_REQUEST_URL_LOG, timestamp, url,JSON.toJSONString(arg) ));
}
}
} else {
if (requestLog.logRequest()) {
if (requestLog.isDebug()) {
requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_REQUEST_URL_PARAM_LOG, timestamp, url));
} else {
requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_REQUEST_URL_PARAM_LOG, timestamp, url));
}
}
}
Object returnValue = pjp.proceed();
//实现了返回值的日志输出
if (requestLog.logReturn()) {
if (requestLog.isDebug()) {
requestLog.logName().getLogger().debug(String.format(LogConfig.HTTP_RESPONSE_RESULT_LOG, timestamp, JSON.toJSONString(returnValue)));
} else {
requestLog.logName().getLogger().info(String.format(LogConfig.HTTP_RESPONSE_RESULT_LOG, timestamp,JSON.toJSONString(returnValue)));
}
}
return returnValue;
}
}
使用案例
/**
* @author dzp
* @since 2019/5/29
* 测试接口 无任何意义
*/
@RestController
@CrossOrigin(value = "*", maxAge = 3600)
@RequestLog
public class TestController {
/**
* @return
*/
@RequestMapping("/test")
public ResponseResult<Object> test(String msg){
return ResponseResult.success();
}
}
启动项目调用该接口:
http://localhost:8888/test?msg=test
成功截图
学习java群
java交流群:868794080
源码地址