一个好的日志输出对于问题的定位是有很大的帮助,本文通过springboot的aop实现了controller日志统一输出的,有需要的童鞋可直接开箱即用:
为更灵活的实现api日志控制效果,小可采用的是自定义注解的方式实现。以下为自定义的注解:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ControllerLogger {
String modul() default "";
String type() default "";
String desc() default "";
}
此处涉及到的相关元注解,大家可自行百度一下就ok了。
接下来就是实现日志输出的逻辑代码了
@Aspect
@Component("controllerLog")
@Slf4j
public class ControllerLog {
@Pointcut("@annotation(com.log.component.aop.ControllerLogger)")
public void logPointCut() {
}
@Around(value = "logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
return process(point);
}
public Object process(ProceedingJoinPoint point) throws Throwable {
System.out.println("\n");
log.info("========================== " + getCurrentMethodName(point) + " starting =============================");
long beginTime = System.currentTimeMillis();
log.info("开始时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss").format(new Date()));
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = null;
if (attributes.getRequest() != null) {
request = attributes.getRequest();
}
log.info("API :" + request.getRequestURI());
log.info("类方法 : " + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
log.info("请求方式:" + request.getMethod());
log.info("请求参数 : " + Arrays.toString(getParams(point)));
Object result = point.proceed();
log.info("返回结果 : " + result);
log.info("结束时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss").format(new Date()));
long time = System.currentTimeMillis() - beginTime;
log.info("耗时 : " + time);
log.info("========================== " + getCurrentMethodName(point) + " ending =============================\n");
return result;
}
// @Before(value = "logPointCut()")
// private void before(JoinPoint point) {
// log.info("========================== " + getCurrentMethodName(point) + " starting =============================");
// }
// @After(value = "logPointCut()")
// private void after(JoinPoint point) {
// log.info("========================== " + getCurrentMethodName(point) + " ending =============================");
//
// }
@AfterThrowing(value = "logPointCut()", throwing = "e")
private void throwAfter(JoinPoint point, Exception e) {
log.error(e.getMessage());
log.info("========================== " + getCurrentMethodName(point) + " ending =============================\n");
}
public String getCurrentMethodName(JoinPoint point) {
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Object target = point.getTarget();
try {
return target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes()).getName();
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public Object[] getParams(JoinPoint point) {
if (point.getArgs().length == 0) {
return new Object[]{};
}
return point.getArgs();
}
}
至此,相关日志工具就开发完成了。