前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用AOP打印日志Controller和DubboService的请求参数和相应参数和响应时间

使用AOP打印日志Controller和DubboService的请求参数和相应参数和响应时间

作者头像
王念博客
发布2019-07-25 18:47:58
1.9K0
发布2019-07-25 18:47:58
举报
文章被收录于专栏:王念博客王念博客

前言:项目为了方便排查问题都会在请求的接口或者暴露的服务前后都会打上日志。这样就搬出了Spring核心功能AOP,前两天我问一年工作经验的javaer,AOP是干啥用的,他回答面向切面编程,打印日志用的。 其实AOP不仅仅为了只是为了打印日志,在声明式事务注解和缓存注解和锁注解和异步注解或者任务调度注解都是动态代理对象执行的,对于动态代理和静态代理或者没有接口使用cglib的实现原理抽空再写一篇。但是今天我们就用AOP来实现拦截所有Controller和DubboService打印日志,因为springmvc的拦截器不能拿到postBody的值。

代码语言:javascript
复制
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的拦截器代码

代码语言:javascript
复制
/**
 * 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;
        }
    }
}

博客地址:https://my.oschina.net/wangnian

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档