自定义注解+aop实现日志收集

背景

生产环境有许多数据是保密的,需要对查看、导出、更新等操作。保存相关的日志信息。(记录操作人、IP地址、浏览器名称、操作模块、方法名称等)

功能实现

一、 自定义注解

/**
 * 		1.CONSTRUCTOR:用于描述构造器
 * 		2.FIELD:用于描述域
 * 		3.LOCAL_VARIABLE:用于描述局部变量
 * 		4.METHOD:用于描述方法
 * 		5.PACKAGE:用于描述包
 * 		6.PARAMETER:用于描述参数
 * 		7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
 * 		    1.SOURCE:在源文件中有效(即源文件保留)
 * 	        2.CLASS:在class文件中有效(即class保留)
 * 	        3.RUNTIME:在运行时有效(即运行时保留)
 * 标注的方法为切点 用来记录日志
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface LogAnnotation {
    /**
     * 主模块
     */
    public String mainModule() default "";
    /**
     * 子模块
     */
    public String submodule() default "";
}


二、AOP

@Slf4j
@Aspect
@Component
public class DirectPayDataOperateAspect {
    //指向自定义的注解接口,告诉切面类,只对使用该注解的方法才执行
    @Pointcut("@annotation(com.huatek.figure.common.interfaces.LogAnnotation)")
    public void loggableMethods() {

    }
    @Before("loggableMethods()")
    public void logMethod(JoinPoint jp) {
        String methodName = jp.getSignature().getName();
        log.info("Executing method: " + methodName);
    }
    // 声明环绕通知
    @Around("loggableMethods()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
            Long startTime = System.currentTimeMillis();
            //要增强的方法的返回结果
            Object ret = pjp.proceed();
            // 获取request对象
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            save(user,request,pjp);
            Long endTime = System.currentTimeMillis();
            log.info("总耗时{}m:响应数据{}", (endTime - startTime)/1000, JSON.toJSONString(ret));
            return ret;
    }

    /**
     * 保存操作
     *
     * @param user
     * @param request
     * @param pjp
     */
    public void save(UserInfo user, HttpServletRequest request, ProceedingJoinPoint pjp) {
        //1.操作人
        //2.时间
        //3.IP地址
        //4.操作模块
        //5.更新、插入
        //6.浏览器
        LogAnnotation logAnnotation = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(LogAnnotation.class);
        log.info("日志信息:{}",JSON.toJSONString(logAnnotation));
        //获取ip地址
        String ipAddress = getIpAddress(request);
        //获取浏览器名称及版本
        String browserName = browserName(request);
        //调用方法将数据保存到table表中
        //添加日志,把request数据封装保存起来,根据项目需要存储即可
        log.info("IP地址为:{},浏览器名称及版本:{},用户:{},操作模块:{},{}",ipAddress,browserName,user.getUserName(),logAnnotation.mainModule(),logAnnotation.submodule());
    }

    /**
     * 获取浏览器名称及版本
     * @param request
     * @return
     */
    public static String browserName(HttpServletRequest request){
        String userAgent = request.getHeader("User-Agent");
        UserAgent ua = UserAgent.parseUserAgentString(userAgent);
        Browser browser = ua.getBrowser();
        return browser.getName() + "-" + browser.getVersion(userAgent);
    }
    /**
     * 获取IP地址
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

三、功能测试


@RestController
public class ProjectFundController {

   @LogAnnotation(mainModule = "主模块一",submodule = "子模块一")
   @RequestMapping(value = "/test", method = RequestMethod.GET)
   public void test() {
     return "日志打印"
   }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值