spring boot项目统一日志打印

在项目开发过程中,日志的打印是必不可少的,平常大部分都是针对单文件打印日志:如下所示

首先在class里面引入日志,

private static final Logger logger = LoggerFactory.getLogger(A.class);

然后在方法里面,针对逻辑打印日志,如:

method A(){

   logger.erroe("XXXXX");

}

method B(){

   logger.erroe("XXXXX");

}

这样有一个繁琐的地方就是每个需要打印日志的地方,都需要调用一遍logger.erroe("XXXXX");方法。于是我们就想着能够在一个地方调用logger.erroe("XXXXX");即可, 下面展示通过spring aop来做统一日志的管理代码如下

写法一、

package com.fpi;

import com.fpi.prd.des.api.vo.mobile.JResult;
import org.apache.commons.lang3.StringUtils;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
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.util.Arrays;


@Aspect
@Configuration
@Component
public class MobileAspect {
   private static final JResult ERRO_RESULT = new JResult(null, JResult.State.DEFAULT);

   private static final Logger logger = LoggerFactory.getLogger(MobileAspect.class);

   //定义v1包下所有的类中的所有方法都需要被执行excudeService方法
   //@Pointcut("execution(* com.fpi.prd.des.api.v1.*.*(需要被执行excudeService方法..))")
  //定义 WmsController或 AqmsController下的所有方法都 
@Pointcut("execution(* com.fpi.prd.des.api.v1.WmsController.*(..)) || execution(* com.fpi.prd.des.api.v1.AqmsController.*(..))")
   public void excudeService() {
   }

   @Around("excudeService()")
   public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
      JResult jResult;
      long start = System.currentTimeMillis();
      try {
         Object result = pjp.proceed();
         jResult = new JResult(result);
      } catch (Exception e) {
         String info = e.getMessage();
         if (StringUtils.isNotBlank(info)) {
            jResult = new JResult(null, JResult.State.DEFAULT);
            jResult.setMessage(info);
         } else {
            jResult = ERRO_RESULT;
         }
         logger.error(e.getMessage());
      }
      if (logger.isInfoEnabled()) {
         RequestAttributes ra = RequestContextHolder.getRequestAttributes();
         ServletRequestAttributes sra = (ServletRequestAttributes) ra;
         HttpServletRequest request = sra.getRequest();
         String uri = request.getRemoteAddr();
         int port = request.getRemotePort();
         logger.info(uri + ":" + port + "请求" + pjp.getSignature().getDeclaringType().getSimpleName() + "."
                 + pjp.getSignature().getName()
                 + Arrays.toString(pjp.getArgs())
                 + "     [耗时:"
                 + (System.currentTimeMillis() - start + "ms]") + request.getQueryString());
      }
      return jResult;
   }
}

在以上的代码中我们只在异常抛出的时候,调用了logger.eeor方法,这样就避免重复调用该方法了

写法二

切面

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;


@Aspect
@Component
public class LoggerAdvice {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    
    @Before(value = "@annotation(loggerManage)")
    public void addBeforeLogger(JoinPoint joinPoint, LoggerManage loggerManage) {
        LocalDateTime now = LocalDateTime.now();
        logger.info(now.toString() + "执行[" + loggerManage.logDescription() + "]开始");
        logger.info(joinPoint.getSignature().toString());
        logger.info(parseParames(joinPoint.getArgs()));
    }

    @AfterReturning(" @annotation(loggerManage)")
    public void addAfterReturningLogger(JoinPoint joinPoint, LoggerManage loggerManage) {
        LocalDateTime now = LocalDateTime.now();
        logger.info(now.toString() + "执行 [" + loggerManage.logDescription() + "] 结束");
    }

    @AfterThrowing(pointcut = "@annotation(loggerManage)", throwing = "ex")
    public void addAfterThrowingLogger(JoinPoint joinPoint, LoggerManage loggerManage, Exception ex) {
        LocalDateTime now = LocalDateTime.now();
        logger.error(now.toString() + "执行 [" + loggerManage.logDescription() + "] 异常", ex);
    }

    private String parseParames(Object[] parames) {
        if (null == parames || parames.length <= 0) {
            return "";
        }
        StringBuffer param = new StringBuffer("传入参数 # 个:[ ");
        int i = 0, j = 0;
        for (Object obj : parames) {
            j++;
            if (obj != null) {
                i++;
                if (j != parames.length) {
                    param.append(obj.toString()).append(" ,");
                } else {
                    param.append(obj.toString());
                }
            }
        }
        return param.append(" ]").toString().replace("#", String.valueOf(i));
    }
}

 

自定义注解

import java.lang.annotation.*;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoggerManage {
    public String logDescription();
}

使用

@RequestMapping(value = "/test", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
    @ResponseBody
    @LoggerManage(logDescription = "测试测试")
    public Map<String, Object> getTest() throws IOException {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        return resultMap;
    }

 

下面博客链接是pointcut配置需要执行的方法的配置解释:

https://blog.csdn.net/bird_tp/article/details/90240887

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值