使用AOP打印日志Controller和DubboService的请求参数和相应参数和响应时间
2019-03-21 15:36
423 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ZuiChuDeQiDian/article/details/95681912
撸了今年阿里、网易和美团的面试,我有一个重要发现.......>>>
前言:项目为了方便排查问题都会在请求的接口或者暴露的服务前后都会打上日志。这样就搬出了Spring核心功能AOP,前两天我问一年工作经验的javaer,AOP是干啥用的,他回答面向切面编程,打印日志用的。 其实AOP不仅仅为了只是为了打印日志,在声明式事务注解和缓存注解和锁注解和异步注解或者任务调度注解都是动态代理对象执行的,对于动态代理和静态代理或者没有接口使用cglib的实现原理抽空再写一篇。但是今天我们就用AOP来实现拦截所有Controller和DubboService打印日志,因为springmvc的拦截器不能拿到postBody的值。
package com.xxx.xxxx.common.aop; import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.ArrayUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.lang.reflect.Parameter; /** * AOP拦截方法打印参数和返回参数 * * @author wangnian */ @Aspect @Component public class LoggingAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 拦截所有controller包下的方法 */ @Pointcut("execution(* com.xxxx.xxx..controller..*.*(..))") private void controllerMethod() { } /** * 拦截dubbo服务所有的方法 */ @Pointcut("@within(org.apache.dubbo.config.annotation.Service)") public void DubboServiceMethod() { } @Around("DubboServiceMethod() || controllerMethod()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { // 所在的类.方法 String msgInfo = "@AOP日志[" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "]"; String requestStr = getRequestParam(joinPoint); logger.info(msgInfo + "start.输入参数:" + requestStr); long startTime = System.currentTimeMillis(); Object result = null; try { // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行 result = joinPoint.proceed(); } catch (Exception e) { //如果有异常继续抛 throw e; } finally { long handleTime = System.currentTimeMillis() - startTime; String responseStr = result == null ? "无" : JSON.toJSONString(result); StringBuffer endString = new StringBuffer(100); endString.append(msgInfo).append("end."); endString.append("耗时(" + handleTime + "ms)"); endString.append("输出参数:").append(responseStr); logger.info(endString.toString()); } return result; } /** * 获取请求参数 * * @param point * @return */ private String getRequestParam(ProceedingJoinPoint point) { Object[] methodArgs = point.getArgs(); Parameter[] parameters = ((MethodSignature) point.getSignature()).getMethod().getParameters(); String requestStr; try { requestStr = logParam(parameters, methodArgs); } catch (Exception e) { requestStr = "获取参数失败"; } return requestStr; } /** * 拼接请求参数 * * @param paramsArgsName * @param paramsArgsValue * @return */ private String logParam(Parameter[] paramsArgsName, Object[] paramsArgsValue) { if (ArrayUtils.isEmpty(paramsArgsName) || ArrayUtils.isEmpty(paramsArgsValue)) { return ""; } StringBuffer buffer = new StringBuffer(); for (int i = 0; i < paramsArgsValue.length; i++) { //参数名 String name = paramsArgsName[i].getName(); //参数值 Object value = paramsArgsValue[i]; buffer.append(name + "="); if (value instanceof String) { buffer.append(value + ","); } else { buffer.append(JSON.toJSONString(value) + ","); } } return buffer.toString(); } }
代码在这里了,没空整理理论,先用起来再深入把。
送一个springmvc的拦截器代码
/** * springMvc拦截器 * * @author wangnian * @date 2019-03-04 */ public class UrlInterceptor extends HandlerInterceptorAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(UrlInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { try { //如果是OPTIONS的请求,不要打印日志 if (RequestMethod.OPTIONS.toString().equals(request.getMethod())) { return true; } LOGGER.info("请求地址:{},请求方式:{},请求的IP:{},User-Agent:{}", request.getRequestURL(), request.getMethod(), IpUtil.getRemoteIp(request), request.getHeader("User-Agent")); return true; } catch (Exception e) { LOGGER.error("请求拦截异常:{}", e); return false; } } }
相关文章推荐
- SpringMvc使用aop进行请求和响应的日志打印
- Spring Boot使用AOP在控制台打印请求、响应信息
- SpringAOP实现拦截Controller请求参数并输出到日志
- springboot aop 打印请求参数 响应参数
- Spring AOP日志记录接口请求参数,执行时间
- 使用 aop拦截 springMVC的controller并获取请求参数及返回结果
- android,retrofit,okhttp,日志拦截器,使用拦截器Interceptor统一打印请求与响应的json
- 使用JavaScript定时刷新,请求响应时间慢慢变长
- Spring Boot(十一)使用AOP,@Aspect统一处理Web请求日志
- SSM项目使用AOP创建统一处理请求日志
- 使用springmvc利用baseController自动收集请求参数
- [置顶] 使用拦截器获取请求参数信息并写入日志
- 详解AOP与Filter拦截请求打印日志实用例子
- 使用Spring AOP预处理Controller的参数
- Spring Boot中使用AOP统一处理Web请求日志
- retrofit2.0使用拦截器Interceptor统一打印请求与响应的json
- 14.Spring-Boot中使用AOP统一处理Web请求日志
- SpringBoot中使用AOP打印接口日志的方法
- Okhttp设置请求日志过滤器,支持打印Post请求参数
- Spring Boot中使用AOP统一处理Web请求日志