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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
springboot+mybatis+dubbo+aop日志第三篇
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等。
写代码的猿
2019/04/11
6630
Spring AOP 切面@Around注解的具体使用
比如我们想在执行controller中方法前打印出请求参数,并在方法执行结束后来打印出响应值,这个时候,我们就可以借助于@Around注解来实现;
全栈程序员站长
2022/09/14
3.1K0
Java AOP实现接口请求日志打印
在学习Spring-cloud框架的时候,正好用到了打印请求参数,Java还好有Aop,不用在请求的时候和返回的时候打日志,统一由Aop来实现,实现很简单
赵哥窟
2022/05/13
9050
SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
知了一笑
2019/07/19
9740
使用注解的方式+AOP校验签名
4.调用方式 (只需要一行代码就可以轻轻松松的进行拦截,想拦截哪就拦截哪) : @CheckSign(title = "****")
用户5927264
2021/09/08
1.1K0
实战:第四章:java后端日志埋点实现
前段时间架构让我弄日志埋点,因为其他工作不断延期,而且到现在也没给明确的需求,这里自己手写一套简单的日志埋点:
Java廖志伟
2022/09/28
9210
实战:第四章:java后端日志埋点实现
【线上排查实战】AOP切面执行顺序你真的了解吗
公司这两个月启动了全新的项目,项目排期满满当当,不过该学习还是要学习。这不,给公司搭项目的时候,踩到了一个Spring AOP的坑。
蛮三刀酱
2020/10/29
6280
【线上排查实战】AOP切面执行顺序你真的了解吗
基于aop实现接口访问的监控记录
此次实践基于spring boot 2.4.1 相关pom <!-- aop 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 监控配置类 import com.alibaba.fastjson.JSON; import org.aspectj.lang.ProceedingJoinPoi
烤红薯
2021/12/23
6750
基于aop实现接口访问的监控记录
使用aop统一处理controller中的异常及日志
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
呼延十
2019/07/01
4.3K0
使用aop统一处理controller中的异常及日志
Spring AOP使用
AOP全程是Aspect—Oriented—Programming,面向切面编程。AOP采用横向抽取机制,将分散在各个方法中的重复代码抽取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。
ha_lydms
2023/08/09
1850
Spring AOP使用
Spring AOP的简单应用
“ 在各种业务场景中,我们可会有打印日志这种语句,通常为了方便我们直接写在业务逻辑的代码中。实际上和业务无关的代码我们也放入到业务逻辑中,会带来了较强的侵入性编码。通常来说,日志和业务代码应该是分离的,而Spring AOP能很好的实现日志和业务代码的分离,当然Spring AOP的作用不仅仅是用来打印日志的,还可以用来做权限控制,缓存等等......”
每天学Java
2020/06/02
3570
Spring-AOP实践 - 统计访问时间
公司的项目有的页面超级慢,20s以上,不知道用户会不会疯掉,于是老大说这个页面要性能优化。于是,首先就要搞清楚究竟是哪一步耗时太多。 我采用spring aop来统计各个阶段的用时,其中计时器工具为StopWatch。 其中,遇到的问题: 1.少包aspectjweaver 添加依赖后才可以使用@Aspect 2.环绕通知加入多个point 刚开使用&&连接多个point,傻傻的看不到调用,忽然看到要用||才对 3.监听时间工具StopWatch每次只能启动一个,一定要关闭后才能启动下一个。 而我想要测试c
Ryan-Miao
2018/03/13
2.2K0
Spring-AOP实践 - 统计访问时间
Java自定义注解:定义、解析,AOP切面与日志打印
本文主要介绍了 Java 中的自定义注解以及结合 AOP(面向切面编程)技术进行日志记录的方法。
Yeats_Liao
2025/01/10
3510
Java自定义注解:定义、解析,AOP切面与日志打印
给SpringBoot接口加全局日志(AOP)
一想到,每个接口都需要加一个开始时间和一个结束时间,我就感觉特别烦,就是不想撸代码。
猿码优创
2019/07/27
2K0
spring AOP日志管理
Spring AOP 完成日志记录 SpringAOPAspectJsecurity日志记录 Spring AOP 完成日志记录 1、技术目标 掌握Spring AOP基本用法 使用Spring AOP完成日志记录功能 2、什么是AOP AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,AOP实际是GoF设计模式的延续 注意:关于AOP的详细介绍不是本文重点 3、关于Spring AOP的一些术语 切面(Aspect):在Spring AOP中,切面
用户1212940
2018/01/23
1.8K0
AOP拦截参数、反回值、执行耗时
import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.Lo
时光_赌徒
2020/12/31
6910
SpringBoot 中用 AOP 实现一个权限校验的思路总结
AOP(Aspect Oriented Programming),面向切面思想,是Spring的三大核心思想之一(两外两个:IOC-控制反转、DI-依赖注入)。
二哥聊运营工具
2021/12/17
1.1K0
SpringBoot 中用 AOP 实现一个权限校验的思路总结
springboot10、AOP
在研发项目的性能测试阶段,或者项目部署后,我们会希望查看服务层方法执行的时间。以便精准的了解项目中哪些服务方法执行速度慢,后续可以针对性的进行性能优化。
红目香薰
2022/11/30
4350
springboot10、AOP
【Spring学习】AOP实现日志记录
AOP,面向切面编程。通过预编译方式和运行时动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
pbinlog
2022/03/21
6960
【Spring学习】AOP实现日志记录
@SysLog – AOP最佳实践:日志规范注解
3、AOP:@Before方法打印日志,@AfterReturning方法处理异常信息
收心
2022/11/07
1.2K0
相关推荐
springboot+mybatis+dubbo+aop日志第三篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验