springboot日志切面记录请求日志

在实际开发场景中,我们需要对代码进行一些参数打印等,在发生异常时,可以通过入参和返回参数进行一些简单的错误定位等。但是,在每个方法下面打印,对代码的入侵性比较大,下面,提供一个日志aop的模板。

AOP技术

简介

这里简单介绍一下AOP,AOP(面向切面编程)是一种编程范式,它允许开发人员在程序的不同部分(切面)中定义横切关注点,并将它们与应用程序的核心业务逻辑分离开来。AOP可以用来实现日志记录、性能监控、事务管理等横切关注点,从而提高代码的模块化和可维护性。在AOP中,切面是一组横切关注点的集合,它们可以在程序的不同部分进行重用,从而减少重复代码的编写。AOP技术通常与面向对象编程结合使用,以实现更灵活和可维护的软件系统。

组成

AOP(面向切面编程)的主要组成部分包括:

切面(Aspect):切面是一组横切关注点的集合,它定义了在程序的不同部分中需要执行的操作。切面可以包括日志记录、性能监控、事务管理等横切关注点。

连接点(Join Point):连接点是在程序执行过程中可以插入切面的点。这些点可以是方法调用、异常处理、变量赋值等。

通知(Advice):通知是切面在特定连接点执行的操作。通知可以是前置通知(在连接点之前执行)、后置通知(在连接点之后执行)、环绕通知(在连接点之前和之后执行)、异常通知(在连接点抛出异常时执行)和最终通知(在连接点执行后执行)。

切点(Pointcut):切点定义了在程序中哪些连接点会被切面影响。它使用表达式来匹配连接点。

引入(Introduction):引入允许向现有的类添加新的方法或属性。

切面类(通过环绕通知实现)

@Slf4j
@Aspect
@Component
public class LogAspect {


    @Pointcut("execution(* com.xxx.xxx.controller.*.*(..))")
    public void pt() {
    }

    @Around(value = "pt()")
    public Object around(ProceedingJoinPoint pjp) {
        Object result = null;
        try {
            // 前置通知
            long startTime = System.currentTimeMillis();
            // 获取url信息
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String url = request.getRequestURL().toString();
            String method = request.getMethod();
            String ip = request.getRemoteAddr();
            String c = pjp.getSignature().getDeclaringType().getName();
            String m = pjp.getSignature().getName();
            String openId = request.getHeader("openId");
            UserThreadLocal.putUser(openId);
            // 进入方法前打印日志
            log.info("请求信息 => url: [{}], method: [{}], ipAddress: [{}], className: [{}], methodName: [{}]", url, method, ip, c, m);
            result = pjp.proceed();
            // 后置通知
            long endTime = System.currentTimeMillis();
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            String className = signature.getDeclaringType().getSimpleName();
            String methodName = signature.getName();
            Object[] args = pjp.getArgs();
            StringBuilder sb = new StringBuilder();
            sb.append(className)
                    .append(".")
                    .append(methodName)
                    .append("(");
            for (int i = 0; i < args.length; i++) {
                sb.append(args[i]);
                if (i < args.length - 1) {
                    sb.append(",");
                }
            }
            sb.append(")");
            // 记录方法执行时间、参数和返回值
            log.info("Method: {},Execution time: {}ms,Result: {}", sb, (endTime - startTime), result);
            log.info("正在释放内存 openid: {}", UserThreadLocal.getUser());
            UserThreadLocal.remove();
            return result;
        } catch (Throwable e) {
            log.info("发生异常: {}", e.getMessage());
            UserThreadLocal.remove();
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值