有些日志信息希望可以写入数据库便于分析,有些日志不需要,这时可以自定义一个日志注解,通过AOP来动态配置需要写入日志的方法。
第一步:定义注解,方法级别 value是可以是该方法的中文解释
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { String value() default ""; }
第二步:编写切面类
@Aspect @Component public class LogAspect { private static final Logger logger = LoggerFactory.getLogger(LogAspect.class); @Autowired private SYSLogService logService; @Pointcut("@annotation(com.bxlsj.base.annotation.Log)") public void logPointCut() { } @Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); // 执行方法 Object result = point.proceed(); // 执行时长(毫秒) long time = System.currentTimeMillis() - beginTime; //异步保存日志 saveLog(point, time); return result; } void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SYSLog sysLog = new SYSLog(); Log syslog = method.getAnnotation(Log.class); if (syslog != null) { // 注解上的描述 sysLog.setOperation(syslog.value()); } // 请求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); sysLog.setMethod(className + "." + methodName + "()"); // 请求的参数 Object[] args = joinPoint.getArgs(); try { String params = JSONUtils.beanToJson(args[0]).substring(0, 4999); sysLog.setParams(params); } catch (Exception e) { } // 获取request HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); // 设置IP地址 sysLog.setIp(IPUtils.getIpAddr(request)); // 用户名 SsoUser currUser = UserThreadLocal.getUSER().get(); if (null == currUser) { if (null != sysLog.getParams()) { sysLog.setUserId(-1L); sysLog.setUsername(sysLog.getParams()); } else { sysLog.setUserId(-1L); sysLog.setUsername("获取用户信息为空"); } } else { sysLog.setUserId(-1L); sysLog.setUsername(currUser.getAccount()); } sysLog.setTime((int) time); // 系统当前时间 Date date = new Date(); sysLog.setGmtCreate(date); // 保存系统日志 logService.save(sysLog); } }
写入数据库的结果如下: