Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用AOP打印日志Controller和DubboService的请求参数和相应参数和响应时间

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

作者头像
王念博客
发布于 2019-07-25 10:47:58
发布于 2019-07-25 10:47:58
2.1K00
代码可运行
举报
文章被收录于专栏:王念博客王念博客
运行总次数:0
代码可运行

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
/**
 * 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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python-基础02-程序与用户交互
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
7840
Python-基础02-程序与用户交互
关于python,这些知识点你学会了吗?
•其他语言运行完之前,一定要手动把程序的内存空间释放掉。但python解释器是自带内存回收机制的,一旦python程序运行完后,会自动释放内存空间。
我被狗咬了
2019/09/23
4690
Python的交互和注释介绍
如何能让Python识别读取用户的输入,就像windows安装程序那样傻瓜式的交互呢,下面我们简单介绍一下Python的交互输入输出。
后场技术
2020/09/03
5290
Python基础语法知识点汇集「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/152646.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/12
4990
Python基础语法知识点汇集「建议收藏」
python基本操作(四)
name = raw_input('请输入你的姓名:') pwd = raw_input('请输入你的密码:') print(type(name)) # 'str' print(type(pwd)) # 'str'
py3study
2020/01/15
3970
Python之禅---3、变量、用户
        变量即变化的量,核心就是“变”和“量”二字,变即变化,量即衡量状态。
py3study
2020/01/09
4900
python输入与输出
%表示格式化操作,% 前面的字符串中的%s(格式符) 使用 % 后面的字符串 'abc' 替换。
py3study
2020/01/09
1.4K0
【从零学习python 】05. Python中的输出和输入
在python3里,print只能使用函数的方式来调用,而在python2里,print可以当做一个命令来使用。
全栈若城
2024/02/29
2450
【从零学习python 】05. Python中的输出和输入
预先学习第一天:计算机基础知识+python简介+快速入门,笔记
今日内容: 1.计算机基础知识 2.python简介 3.快速入门 昨日回顾 1.无 内容详细: 一.计算机基础 1. 计算机什么组成的 输入输出设备 cpu 硬盘 内存 中央处理器 处理各种数据 相当于人的大脑 内存 存储数据 硬盘 存储数据的 2. 什么是操作系统 控制计算机工作的流程 软件 什么是应用程序 安装在操作系统之上的软件 就是应用程序 总结: cpu 人的大脑 内存
changxin7
2019/09/10
5410
Python2input和raw_inp
Python3的input和Python的raw_inpu一样,用户交互数据数据的时候不需要加双引号,用户输入数据的时候默认是字符串类型
py3study
2020/01/06
4000
python简单学-----------
2.对中文的支持 python2和python3不一样,python3默认支持,python2 需要加上
py3study
2020/01/20
8160
一、python入门
一、python介绍 介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum)。1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器。Python这个名字,来自Guido所挚爱的电视剧Monty Python’s Flying Circus。他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。 最新的TIOBE排行榜,Python赶超PHP占据第4, Python崇尚优美、清晰、
py3study
2020/01/09
5540
Python入门
多媒体应用、WEB开发、网络爬虫、人工智能与机器学习、数据分析处理、服务器运维及其他小工具 知乎链接:用python做一些有趣的事情
潇洒坤
2018/09/10
1.3K0
Python入门
简述Python2与Python3的区别
超出上述范围,python自动转化为long(长整型) 注:long(长整型)数字末尾有一个L
py3study
2020/01/16
6010
python2与python3中input的区别
python2与python3 的区别:   1、input: python2中input需要用户指定输入的类型,以下代码体现了这点
全栈程序员站长
2022/09/08
5260
Python获取控制台输入
Python获取控制台输入有两种方式:input()和raw_input Python3之后raw_input()已经被删除了。 Python2中有input和raw_input两个函数,其中raw_input将所有输入作为字符串看待,返回字符串类型。input函数支持表达式、数字类型、字符串类型,接受为表达式时,只返回其执行结果。 在Python3中对input和raw_input函数进行了整合,仅保留了input函数(认为raw_input函数是冗余的)。同时改变了input的用法——将所有的输入按照字
py3study
2020/01/13
2.1K0
python基础-变量运算符(3)
注释就是对代码的解释和说明。目的是为了让别人和自己很容易看懂。为了让别人一看就知道这段代码是做什么用的。正确的程序注释一般包括序言性注释和功能性注释。序言性注释的主要内容包括模块的接口、数据的描述和模块的功能。模块的功能性注释的主要内容包括程序段的功能、语句的功能和数据的状态。–来自百度百科
Se7eN_HOU
2019/06/28
6570
python基础-变量运算符(3)
Python 内置函数大全(上)
divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
Python知识大全
2020/02/13
5660
笨办法学Python - 习题11-12
1、在 Python2.x 中 raw_input( ) 和 input( ),两个函数都存在,具体区别详情请参考习题5,其中区别为:
py3study
2020/02/10
5270
python3--变量,布尔值,用户交互 input,if语句,while循环
已经运行了第一个python程序,即:终端---->cmd----->python 文件路劲。回车搞定~
py3study
2018/08/02
1.7K0
相关推荐
Python-基础02-程序与用户交互
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验