SpringBoot+Aop搭建系统日志

日志预览

SpringBoot+Aop搭建系统日志

自定义注解

import java.lang.annotation.*;

@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
   /**
    * 操作类型(enum):添加,删除,修改,登陆
    */
   LogOperateTypeEnum operationType() ;

   //操作内容(content)
   String operateContent();
}

自定义枚举(操作类型)

package com.cetron.common;
public enum LogOperateTypeEnum {

   ADD("添加",1),

   DEL("删除",2),

   UPDATE("修改",3),

   LOGIN("登陆",4);
   private String operateDesc;
   private int operateCode;


    LogOperateTypeEnum(String operateDesc,int operateCode){
       this.operateDesc=operateDesc;
       this.operateCode=operateCode;
   }

   public static String getMessage(int operateCode){
       //通过enum.values()获取所有的枚举值
       for(LogOperateTypeEnum logOperateTypeEnum : LogOperateTypeEnum.values()){
           //通过enum.get获取字段值
           if(logOperateTypeEnum.getOperateCode() == operateCode){
               return logOperateTypeEnum.operateDesc;
           }
       }
       return null;
   }

   public String getOperateDesc() {
       return operateDesc;
   }

   public int getOperateCode() {
       return operateCode;
   }

   public void setOperateDesc(String operateDesc) {
       this.operateDesc = operateDesc;
   }

   public void setOperateCode(int operateCode) {
       this.operateCode = operateCode;
   }
}

获得ip地址的工具类

package com.cetron.common.utils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class IpUtil {
   public static String getIpAddr(HttpServletRequest request) {
       String ipAddress = null;
       try {
           ipAddress = request.getHeader("x-forwarded-for");
           if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
               ipAddress = request.getHeader("Proxy-Client-IP");
           }
           if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
               ipAddress = request.getHeader("WL-Proxy-Client-IP");
           }
           if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
               ipAddress = request.getRemoteAddr();
               if (ipAddress.equals("127.0.0.1")) {
                   // 根据网卡取本机配置的IP
                   InetAddress inet = null;
                   try {
                       inet = InetAddress.getLocalHost();
                   } catch (UnknownHostException e) {
                       e.printStackTrace();
                   }
                   ipAddress = inet.getHostAddress();
               }
           }
           // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
           if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
               // = 15
               if (ipAddress.indexOf(",") > 0) {
                   ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
               }
           }
       } catch (Exception e) {
           ipAddress="";
       }
       // ipAddress = this.getRequest().getRemoteAddr();

       return ipAddress;
   }
}

在实现类的具体方法上加上注解

 @Override
    @Transactional
    @LogAnnotation(operationType= LogOperateTypeEnum.ADD,operateContent="添加产品线")
    public String addProductLine(String lineName) {
         projectMapper.addProductLine(lineName);
        return lineName;
    }

切面

package com.cetron.aop;
improt ...
@Aspect
@Component
public class LogAspect {
   @Resource
   private LogMapper logMapper;
   private Logger log = Logger.getLogger(getClass());
   //只要使用了该注解,就会进入切面
   @Pointcut("@annotation(com.cetron.aop.LogAnnotation)")
   public void operationLog(){}



   /**
    * 方法返回之后调用
    * @param joinPoint
    * @param returnValue 方法返回值
    */
   @AfterReturning(value = "operationLog()",returning="returnValue")
   public void doAfter(JoinPoint joinPoint,Object returnValue) {
       LogVo logVo= getLogVo(joinPoint,returnValue);
   }

   private LogVo  getLogVo(JoinPoint joinPoint,Object returnValue){
       //登录的session中去拿当前登录的用户Id
       Subject subject = SecurityUtils.getSubject();
       SysUserBaseVo user=null;
       Long currentUserId=null;
       //判断是否通过shiro认证
       if(subject.getPrincipal()!=null) {
            user = (SysUserBaseVo) subject.getPrincipal();
            currentUserId = user.getUserId();
       }
       else {
           return null;
       }

       LogVo logVo = new LogVo();
       //获取类名称
       String targetName = joinPoint.getTarget().getClass().getName();
       Class targetClass = null;
       LogAnnotation logAnnotation = null;
       try {
           //反射
           targetClass = Class.forName(targetName);
           //获得切入点所在类的所有方法
           Method[] methods = targetClass.getMethods();
           //获取切入点的方法名称
           String methodName = joinPoint.getSignature().getName();
           //获取切入点的参数
           Object[] arguments = joinPoint.getArgs();

           //遍历方法名
           for (Method method : methods) {
               if (method.getName().equals(methodName)) {
                   Class[] clazzs = method.getParameterTypes();
                   //比较声明的参数个数和传入的是否相同
                   if (clazzs.length == arguments.length) {
                       //获取切入点方法上的注解
                       logAnnotation = method.getAnnotation(LogAnnotation.class);
                       break;
                   }
               }
           }
           //为日志实体类赋值
           logVo.setLogType(logAnnotation.operationType().getOperateDesc());
           if(returnValue.getClass()== HashMap.class){
               //忽略shiro返回的数据
               logVo.setLogDesc(logAnnotation.operateContent());
           }
           else {
               logVo.setLogDesc(logAnnotation.operateContent() + ":" + returnValue);
           }
           logVo.setLogStartDate(new Date());
           logVo.setUserId(currentUserId);
   		   //获取ip地址
           ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
           HttpServletRequest request = requestAttributes.getRequest();
           logVo.setRequestIp(IpUtil.getIpAddr(request));
           //添加日志
           logMapper.addSysLog(logVo);

       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }

       return logVo;

   }
}

测试

SpringBoot+Aop搭建系统日志

结果

SpringBoot+Aop搭建系统日志