springboot中使用切面注解@Aspect进行日志统一打印

springboot中使用切面注解@Aspect进行日志统一打印

引言

在实际项目中,通常需要将请求controller的参数进行打印,便于查找bug,快速定位问题。如果每个controller中的请求都写上日志,会让代码很凌乱,这里我们就使用spring aop概念,将请求入参统一打印

代码如下

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Aspect  //切面类
@Component //Spring容器管理
public class LogAspect {
    @Pointcut("execution(public * com.xxx.service.controller.*.*(..))")
    public void LogAspect(){}
    
    @Around("LogAspect()")
    public Object deAround(ProceedingJoinPoint pjp) throws Throwable{
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        //ip地址
        String ipaddress;
        if (request.getHeader("x-forwarded-for") == null) {
            ipaddress = request.getRemoteAddr();
        } else {
            ipaddress = request.getHeader("x-forwarded-for");
        }
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String queryString = request.getQueryString();
        Object[] args = pjp.getArgs();
        String params = "";
        //获取请求参数集合并进行遍历拼接
        if(args.length>0){
            if("POST".equals(method)){
                Object object = args[0];
                Map map = getKeyAndValue(object);
                params = JSON.toJSONString(map);
            }else if("GET".equals(method)){
                params = queryString;
            }
        }
		//请求信息打印
        log.info("请求地址:{},请求ip:{},请求类型:{},请求参数:{}",url,ipaddress,method,params);
		//返回信息打印	
		Object result = pjp.proceed();
		Gson gson = new Gson();
		log.info("请求结束===返回值:" + gson.toJson(result));
        return pjp.proceed();
    }

    public static Map<String, Object> getKeyAndValue(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        // 得到类对象
        Class userCla = (Class) obj.getClass();
        /* 得到类中的所有属性集合 */
        Field[] fs = userCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true); // 设置些属性是可以访问的
            Object val;
            try {
                val = f.get(obj);
                // 得到此属性的值
                map.put(f.getName(), val);// 设置键值
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值