Springboot接口项目如何使用AOP记录日志

这篇文章主要介绍了Springboot接口项目如何使用AOP记录日志,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、 背景

一直想给项目构建一个统一的日志收集系统,先迈出第一步,构建一个日志收集类,用AOP实现无侵入日志收集

二、 环境

1.此随笔内容基于spring boot项目

2.数据库MysqL 5.7.9版本

3.jdk 版本为1.8

三、 说明

此版采用数据库存储,之后考虑使用elasticsearch等工具存储

四、 内容

1、构建日志采集实体类:BaseLogMessage

public class BaseLogMessage { private String serverIP; private String appName; private String method; private String type; private String userCode; private String uri; private String operationName; private String operationStatus; private long startTime; private Object parameter; private Object result; private int SpendTime; // 此处省略get、set }

2、构建一个配置文件读取类,用于读取配置文件中的系统名称:SystemPropetiesUtil

@Configuration public class SystemPropetiesUtil { @Value("${spring.application.name}") private String sysName;//系统名称

// 此处省略get、set

}

3、新建一个AOP类,在控制器方法上作为切点,执行日志收集: LogAspect

@Aspect @Component public class LogAspect { @Autowired private SystemPropetiesUtil systemPropetiesUtil; //定义切点方法 @pointcut("execution(public * cq..campus.prevented.controller.*.*(..))") public void controllerLog() { } public static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class); @Around("controllerLog()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); //获取当前请求对象 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //记录请求信息 BaseLogMessage baseLogMessage = new BaseLogMessage(); //1.获取到所有的参数值的数组 Object[] args = joinPoint.getArgs(); Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; //2.获取方法的所有参数名称的字符串数组 String[] parameterNames = methodSignature.getParameterNames(); Object result = joinPoint.proceed(); Method method = methodSignature.getmethod(); if (method.isAnnotationPresent(ApiOperation.class)) { ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); baseLogMessage.setoperationName(apiOperation.value()); } long endTime = System.currentTimeMillis(); String urlStr = 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)); // 数据库存储操作 return result; } /** * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 * * @param joinPoint 切入点 * @param e 异常信息 */ @AfterThrowing(pointcut = "controllerLog()", throwing = "e") public void saveExceptionLog(JoinPoint joinPoint, Throwable e) { long startTime = System.currentTimeMillis(); if(null==kafkaClient){ kafkaClient = KafkaProducerClient.getInstance(systemPropetiesUtil.getKafkaHost()); // redisClient= RedisClient.getInstance(systemPropetiesUtil.getReidsHost(), Integer.parseInt(systemPropetiesUtil.getRedisPort()), ""); } // 获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); // 从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes .resolveReference(RequestAttributes.REFERENCE_REQUEST); String urlStr = request.getRequestURL().toString(); BaseLogMessage baseLogMessage = new BaseLogMessage(); Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getmethod(); StringBuffer strbuff = new StringBuffer(); for (StackTraceElement stet : elements) { strbuff.append(stet + "n"); } String message = exceptionName + ":" + exceptionMessage + strbuff.toString(); try { Object[] args = joinPoint.getArgs(); String[] parameterNames = methodSignature.getParameterNames(); long endTime = 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 (Exception e2) { e2.printstacktrace(); } } /** * 根据方法和传入的参数获取请求参数 */ private Object getParameter(Method method, Object[] args) { List argList = new ArrayList(); Parameter[] parameters = method.getParameters(); for (int i = 0; i map = new HashMap(); String key = parameters[i].getName(); if (!StringUtils.isEmpty(requestParam.value())) { key = requestParam.value(); } map.put(key, args[i]); argList.add(map); } } if (argList.size() == 0) { return null; } else if (argList.size() == 1) { return argList.get(0); } else { return argList; } } /** * 获取请求ip */ public static String getRemoteIP(HttpServletRequest request) { String ip =null; if (ip == null || ip.length() == 0 || "unkNown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Forwarded-For"); } if (ip == null || ip.length() == 0 || "unkNown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unkNown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unkNown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (ip != null) { //对于通过多个代理的情况,最后IP为客户端真实IP,多个IP按照','分割 int position = ip.indexOf(","); if (position > 0) { ip = ip.substring(0, position); } } return ip; } }

五、 问题

1、如果方法正常执行,不进入AOP类,请检查AOP的切点是否书写正确。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...