Springboot接口项目如何使用AOP记录日志
一、背景
一直想给项目构建一个统一的日志收集系统,先迈出第一步,构建一个日志收集类,用AOP实现无侵入日志收集
二、环境
1.此随笔内容基于springboot项目
2.数据库为mysql5.7.9版本
3.jdk版本为1.8
三、说明
此版采用数据库存储,之后考虑使用elasticsearch等工具存储
四、内容
1、构建日志采集实体类:BaseLogMessage
publicclassBaseLogMessage{ privateStringserverIP; privateStringappName; privateStringmethod; privateStringtype; privateStringuserCode; privateStringuri; privateStringoperationName; privateStringoperationStatus; privatelongstartTime; privateObjectparameter; privateObjectresult; privateintSpendTime; //此处省略get、set }
2、构建一个配置文件读取类,用于读取配置文件中的系统名称:SystemPropetiesUtil
@Configuration publicclassSystemPropetiesUtil{ @Value("${spring.application.name}") privateStringsysName;//系统名称
//此处省略get、set
}
3、新建一个AOP类,在控制器方法上作为切点,执行日志收集:LogAspect
@Aspect @Component publicclassLogAspect{ @Autowired privateSystemPropetiesUtilsystemPropetiesUtil; //定义切点方法 @Pointcut("execution(public*cq..campus.prevented.controller.*.*(..))") publicvoidcontrollerLog(){ } publicstaticfinalLoggerLOGGER=LoggerFactory.getLogger(LogAspect.class); @Around("controllerLog()") publicObjectdoAround(ProceedingJoinPointjoinPoint)throwsThrowable{ longstartTime=System.currentTimeMillis(); //获取当前请求对象 ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequestrequest=attributes.getRequest(); //记录请求信息 BaseLogMessagebaseLogMessage=newBaseLogMessage(); //1.获取到所有的参数值的数组 Object[]args=joinPoint.getArgs(); Signaturesignature=joinPoint.getSignature(); MethodSignaturemethodSignature=(MethodSignature)signature; //2.获取到方法的所有参数名称的字符串数组 String[]parameterNames=methodSignature.getParameterNames(); Objectresult=joinPoint.proceed(); Methodmethod=methodSignature.getMethod(); if(method.isAnnotationPresent(ApiOperation.class)){ ApiOperationapiOperation=method.getAnnotation(ApiOperation.class); baseLogMessage.setOperationName(apiOperation.value()); } longendTime=System.currentTimeMillis(); StringurlStr=request.getRequestURL().toString(); baseLogMessage.setUri(urlStr); baseLogMessage.setType("操作日志"); baseLogMessage.setServerIP(getRemoteIP(request)); baseLogMessage.setMethod(request.getMethod()); baseLogMessage.setAppName(systemPropetiesUtil.getSysName()); baseLogMessage.setResult(result); baseLogMessage.setParameter(getParameter(method,joinPoint.getArgs())); baseLogMessage.setSpendTime((int)(endTime-startTime)); baseLogMessage.setStartTime(endTime); LOGGER.info("{}",JsonUtils.objectToJson(baseLogMessage)); //数据库存储操作 returnresult; } /** *异常返回通知,用于拦截异常日志信息连接点抛出异常后执行 * *@paramjoinPoint切入点 *@parame异常信息 */ @AfterThrowing(pointcut="controllerLog()",throwing="e") publicvoidsaveExceptionLog(JoinPointjoinPoint,Throwablee){ longstartTime=System.currentTimeMillis(); if(null==kafkaClient){ kafkaClient=KafkaProducerClient.getInstance(systemPropetiesUtil.getKafkaHost()); //redisClient=RedisClient.getInstance(systemPropetiesUtil.getReidsHost(),Integer.parseInt(systemPropetiesUtil.getRedisPort()),""); } //获取RequestAttributes RequestAttributesrequestAttributes=RequestContextHolder.getRequestAttributes(); //从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequestrequest=(HttpServletRequest)requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); StringurlStr=request.getRequestURL().toString(); BaseLogMessagebaseLogMessage=newBaseLogMessage(); Signaturesignature=joinPoint.getSignature(); MethodSignaturemethodSignature=(MethodSignature)signature; Methodmethod=methodSignature.getMethod(); StringBufferstrbuff=newStringBuffer(); for(StackTraceElementstet:elements){ strbuff.append(stet+"\n"); } Stringmessage=exceptionName+":"+exceptionMessage+strbuff.toString(); try{ Object[]args=joinPoint.getArgs(); String[]parameterNames=methodSignature.getParameterNames(); longendTime=System.currentTimeMillis(); baseLogMessage.setUri(urlStr); baseLogMessage.setType("异常日志"); baseLogMessage.setServerIP(getRemoteIP(request)); baseLogMessage.setMethod(request.getMethod()); baseLogMessage.setAppName(systemPropetiesUtil.getSysName()); baseLogMessage.setResult(message); baseLogMessage.setParameter(getParameter(method,joinPoint.getArgs())); baseLogMessage.setSpendTime((int)(endTime-startTime)); baseLogMessage.setStartTime(endTime); LOGGER.info("{}",JsonUtils.objectToJson(baseLogMessage)); //数据库存储操作 }catch(Exceptione2){ e2.printStackTrace(); } } /** *根据方法和传入的参数获取请求参数 */ privateObjectgetParameter(Methodmethod,Object[]args){ List
五、问题
1、如果方法正常执行,不进入AOP类,请检查AOP的切点是否书写正确。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。