微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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的切点是否书写正确。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐