从0到1带你实现一个业务日志组件(一)需求分析篇

2023年 10月 16日 26.4k 0

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:【架构思想】🍅

✈️本篇内容: 从0到1带你实现一个业务日志组件✈️

🍱本篇收录完整代码地址:gitee.com/diqirenge/b…

楔子

前段时间小七接到一个任务,要为某些后台操作添加业务操作日志,并且需要将日志存储在数据库中。看了看当前项目中的代码,很*很暴力,直接就在对应的地方写的一条插入语句就ok了,抛开技术不谈,这样的代码还是很优雅的!

但是小七想起了以前看过的美团的一篇技术博客——《如何优雅地记录操作日志?》 ,正好有2天时间完成这个需求,时间充足,还等什么?开干

0E026290.gif

分析需求

业务方需求很简单,总结起来就是 把什么人在什么时间对什么东西做了什么操作 给记录下来,当然再做好一点的话,可以将两次操作的不同记录下来。我们这一次就完成基础需求就好了。

确认方案

首先我们来思考一下可行的几种方案:

  • 直接持久化,在需要保存日志的地方写sql就好了。

  • 将保存操作抽象提取为工具类,在需要保存日志的地方,调用工具类。

  • 使用AOP生成操作日志。

  • 使用canal监听数据库变化,记录操作日志。

  • 针对第一点,优势在于不用动脑子;针对第二点,优势在于比第一点动了一点脑子。这两种方案小七都是不推荐的,耦合性太高,拓展性太低。

    针对第三点,也是很多公司采取的方案,但是大家一般都只是,简单的拼接了一下出入参,结合美团的博客——《如何优雅地记录操作日志?》 我们可以考虑使用SpEL来做动态模版。这种方案可行且优雅。

    针对第四点,只能根据数据库的更改做日志记录,局限太大,不考虑。

    综上所述,我们最后选择使用AOP来生成动态的操作日志。

    基础架构

    方案确定了,接下来,我们需要定义一下我们的基础架构。因为是根据AOP来玩的,所以我们需要2个东西,注解和切面。

    分支名称

    231013-52javaee.com-DemandAnalysis

    仓库地址

    gitee.com/diqirenge/b…

    分支描述

    根据需求分析,完成注解设计。

    代码实现

    注解一:业务日志注解 BizLog

    根据需求分析,我们可以抽象出我们需要的日志属性

    需求 翻译
    什么人 操作者
    什么时间 操作时间(这个不需要传入,以系统计算为准)
    什么东西 xx系统,xx模块,xx业务id
    什么操作 操作类型

    以上属性按道理就可以完成我们的需求了,但是为了拓展性,我们可以再添加以下属性

    拓展 翻译
    操作结果 1、成功模板 2、失败模版
    记录条件 根据某些条件,判断是否需要记录日志。比如:证件类型为身份证的才记录
    详情 拓展字段,存放其他不好定义的信息

    具体代码如下:

    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Repeatable(BizLogs.class)
    public @interface BizLog {
        /**
         * 操作者,必填
         */
        String operator();
    
        /**
         * 成功模板,必填
         */
        String success();
    
        /**
         * 系统,默认取spring-application-name
         */
        String system() default "";
    
        /**
         * 模块
         */
        String module() default "";
    
        /**
         * 操作类型:比如增删改查
         */
        String type() default "";
    
        /**
         * 关联的业务id
         */
        String bizNo() default "";
    
        /**
         * 失败模板
         */
        String fail() default "";
    
    
        /**
         * 拓展字段
         * 记录更详细的其他信息
         */
        String detail() default "";
    
        /**
         * 记录条件 默认 true
         * true代表要记录,false代表不记录
         */
        String condition() default "";
    
    }
    
    

    注解解析:

    // 用于指示将被注解的元素包含在生成的Java文档中
    @Documented
    
    // 表明这个注解可以修饰(作用)在方法上
    @Target(ElementType.METHOD)
    
    // 对应Java代码的加载和运行顺序
    // 范围大小:java源文件

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论