封装系统全局操作日志aop拦截且可打包给其他项目依赖

发布时间:2021-10-20 17:09:38 作者:柒染
来源:亿速云 阅读:231

封装系统全局操作日志aop拦截且可打包给其他项目依赖,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在开发过程中,为了更快地排错,更好得了解接口访问量,可以选择用aop做全局的操作拦截,在项目不止一个的时候,我们可以选择独立出来,新项目可以很快的加上全局操作日志,具体代码及数据库表设计如下:

1.数据库MySQL表结构设计,如下图(可根据需要加减字段):
封装系统全局操作日志aop拦截且可打包给其他项目依赖

2.可以根据表结构逆向生成相关实体类及Mapper,此步骤相对简单(略)

3.增加全局日志切面类

**
 * @author songlonghui
 * @ClassName SystemLogAspect
 * @Description 日志切面记录
 * @date 2019/7/24 16:38
 * @Version 1.0
 */
@Component
@Aspect
public class SystemLogAspect {

    private Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);

    @Autowired
    private SystemLogDao systemLogDao;

    /*@Value("${LOG_POINT_URL}")
    private String logPointUrl;*/

    /** 以 controller 包下定义的所有请求为切入点 */
    @Pointcut("execution(public * com.machinsight.*.*.controller..*.*(..)) && !@annotation(com.machinsight.system_log.core.annotation.NoAspectAnnotation)")
    public void webLog() {
        //logger.warn("切点路径---------->" + logPointUrl);
    }

    //private SystemLogWithBLOBs systemLogWithBLOBs;

    /**
     * 在切点之前织入
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 开始打印请求日志
        //logger.info("=========================================== Start ===========================================");
    }

    /**
     * 在切点之后织入
     * @throws Throwable
     */
    @After("webLog()")
    public void doAfter() throws Throwable {
        logger.info("=========================================== End ===========================================");
        // 每个请求之间空一行
        logger.info("");
    }

    /**
     * 环绕
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 开始时间
        long startTime = System.currentTimeMillis();
        SystemLogWithBLOBs systemLogWithBLOBs = new SystemLogWithBLOBs();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null != attributes){
            HttpServletRequest request = attributes.getRequest();
            logger.error("当前线程号:--doAround--" + Thread.currentThread());
            String url = request.getRequestURL().toString();
            String description = proceedingJoinPoint.getSignature().getDeclaringTypeName();
            String requestArgs = FastJsonUtils.toJSONNoFeatures(proceedingJoinPoint.getArgs()).replaceAll("\\\\","");
            String ip = UuidUtil.getIpAddr(request);
            // 打印请求相关参数
            logger.info("========================================== Start ==========================================");
            // 打印请求 url
            logger.info("请求URL            : {}", url);
            // 打印 Http method
            logger.info("HTTP请求方法 Method    : {}", request.getMethod());
            // 打印调用 controller 的全路径以及执行方法
            logger.info("Class--Controller 全路径以及执行方法 Method   : {}.{}", description);
            // 打印请求的 IP
            logger.info("请求IP             : {}", ip);
            // 打印请求入参
            logger.info("请求参数Request Args   : {}", requestArgs);
            // 记录日志入库
            String value = request.getHeader("user-agent");  // 用户代理信息
            //
            systemLogWithBLOBs.setCreateTime(new Date());  // 请求参数
            systemLogWithBLOBs.setMethod(url);  // 接口地址
            systemLogWithBLOBs.setRequestIp(ip);  //请求ip
            systemLogWithBLOBs.setRequestArgs(requestArgs);  // 请求参数
            systemLogWithBLOBs.setUserAgent(value); // 用户代理信息
            systemLogWithBLOBs.setDescription(description);
        }
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();

            String responseArgs = FastJsonUtils.toJSONNoFeatures(result).replaceAll("\\\\","");

            long useTime = System.currentTimeMillis() - startTime;

            // 打印出参
            logger.info("具体返回参数 Response Args  : {}", responseArgs);
            // 执行耗时
            logger.info("整体执行耗时 Time-Consuming : {} ms", useTime);
            systemLogWithBLOBs.setResponseArgs(responseArgs);
            systemLogWithBLOBs.setTimeConsuming(Integer.valueOf(String.valueOf(useTime)));
        } catch (Throwable throwable) {
            // 设置异常信息
            systemLogWithBLOBs.setIsException(1);
            // 异常信息
            systemLogWithBLOBs.setExceptionDetail(throwable.getMessage());
            // 耗时
            long exceptionTime = System.currentTimeMillis() - startTime;
            systemLogWithBLOBs.setTimeConsuming(Integer.valueOf(String.valueOf(exceptionTime)));
            // 异常返回参数
            JsonResult jsonResult = new JsonResult();
            jsonResult.setMsg(CrmConstant.OPS_FAILED_MSG);
            jsonResult.setSuccess(CrmConstant.OPS_FAILED_CODE);
            jsonResult.setData(throwable.getMessage());
            String responseArgsForException = FastJsonUtils.toJSONNoFeatures(jsonResult);
            systemLogWithBLOBs.setResponseArgs(responseArgsForException);
            // 抛出异常
            throw new Throwable(throwable.getMessage());
        } finally {
            systemLogDao.insertSelective(systemLogWithBLOBs);
        }
        return result;
    }

4.可根据公司项目的整体包结构配置切点,还可以增加不需要拦截的配置,为了更灵活细化,这里增加了相应注解类,如下:

/**
 * 切面排除注解类
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NoAspectAnnotation {

}

5.只要在不需要的拦截的controller方法加上注解@NoAspectAnnotation即可,切点会自动排除:

/**
 * @author songlonghui
 * @ClassName CommonController
 * @Description TODO
 * @date 2019/8/23 16:09
 * @Version 1.0
 */
@Controller
@RequestMapping("common")
public class CommonController {

    @ResponseBody
    @RequestMapping("/test")
    @NoAspectAnnotation
    public String testLog(@RequestBody String inputJson) throws Exception{
        String msg = "操作成功";
        return msg;
    }

}

6.只要在别的项目中增加该项目依赖即可:

<!-- 全局日志切面 -->
<dependency>
   <groupId>com.machinsight</groupId>
   <artifactId>system_log</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <exclusions>
      <exclusion>
         <artifactId>*</artifactId>
         <groupId>*</groupId>
      </exclusion>
   </exclusions>
</dependency>

有需要整体项目源码的朋友可以联系我,现在还没有想好源码放在什么地方供别人下载!!
邮箱地址:lance911215@outlook.com

关于封装系统全局操作日志aop拦截且可打包给其他项目依赖问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. QML全局按键监视、拦截
  2. Spring AOP实现系统日志功能

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

aop

上一篇:如何理解携程架构部开源的配置中心Apollo

下一篇:付费SOCKS5代理的好处有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》