首页 > 其他分享 >通用操作日志组件 - mzt-biz-log

通用操作日志组件 - mzt-biz-log

时间:2024-11-12 10:46:00浏览次数:1  
标签:mzt log bizNo private biz newOrder 日志 public

1、什么是mzt-biz-log

  • 此组件解决的问题是: 「谁」在「什么时间」对「什么」做了「什么事」

  • 简单来讲,就是来用记录谁在什么时间做了什么事情

git地址:https://github.com/mouzt/mzt-biz-log

2、为什么是使用 mzt-biz-log

  • 减少重复造轮子。

3、mzt-biz-log 入门操作

1、maven依赖添加依赖

    <dependency>
      <groupId>io.github.mouzt</groupId>
      <artifactId>bizlog-sdk</artifactId>
      <version>3.0.6</version>
    </dependency>

2、SpringBoot入口,添加 @EnableLogRecord 注解

  • tenant是代表当前系统的标识
@SpringBootApplication
@EnableConfigurationProperties
@EnableLogRecord(tenant = "com.mzt.test")
public class Main {

  public static void main(String[] args) {
    SpringApplication.run(Main.class, args);
  }
}

3、日志埋点

  • success:方法成功后记录在日志的内容中.

  • fail:需要开启才会与你抛出异常则记录fail的日志,#_errorMsg 是取的方法抛出异常后的异常的 errorMessage。

  • type:类型标识

  • bizNo:业务的 ID

  • extra:参数详情。这里的 #request.toString() 是调用了 LogOperation的 toString() 方法。 想要保存 JSON,重写一下 LogOperation 的 toString() 方法就可以。

支持SpEL 表达式,可以调用静态方法,三目表达式

    @PostMapping("/add")
    @LogRecord(success = "新增日志测试,用户名:「{{#request.operatorName}}」,类型:「{{#request.type}}」,状态:「{{#request.status == 0?'禁用':'启动'}}」,操作时间:「{{#createTime}}」",
            fail = "方法失败,失败原因:「{{#_errorMsg}}」",
            type = "add",
            bizNo = "",
            extra = "{{#request.toString()}}")
    public void add(@Valid @RequestBody LogOperation request) {
		LogRecordContext.putVariable("createTime", LocalDateTime.now());
        System.out.println("日志测试");
    }

此时会打印日志: "新增日志测试,用户名:「张三」,类型:「add」,状态:「启动」,操作时间:「2024-11-12T09:22:40.491」"

4、将日志保存到数据库

实现 ILogRecordService 重写 record 方法

@Service
public class DbLogRecordServiceImpl implements ILogRecordService {

    @Autowired
    private LogOperationMapper logOperationMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void record(LogRecord logRecord) {
        log.info("【logRecord】log={}", logRecord);
        // 可以转换成自己数据库的对象
        LogOperation operate = new LogOperation(logRecord);
        logOperationMapper.insert(operate);
    }

    @Override
    public List<LogRecord> queryLog(String bizKey, Collection<String> types) {
        return Lists.newArrayList();
    }

    @Override
    public PageDO<LogRecord> queryLogByBizNo(String bizNo, Collection<String> types, PageRequestDO pageRequestDO) {
        return logRecordMapper.selectByBizNoAndCategory(bizNo, types, pageRequestDO);
    }
}

5、指定日志操作人

有两种方法:

  • 直接在 @LogRecord 指定 currentUser。如:@LogRecord(operator = "{{#currentUser}}"),需要参数上有:currentUser。

public boolean createOrder(Order order, String currentUser)

  • 实现IOperatorGetService类来自动的获取操作人
@Service
public class DefaultOperatorGetServiceImpl implements IOperatorGetService {

    @Override
    public OperatorDO getUser() {
        OperatorDO operatorDO = new OperatorDO();
        operatorDO.setOperatorId("SYSTEM");
        return operatorDO;
    }
}

4、高级用法

1、使用 condition,满足条件的时候才记录日志

condition 中的 SpEL 表达式必须是 bool 类型才生效

    @LogRecord(success = "更新了订单ORDER{#orderId}},更新内容为...",
            type = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}",
            extra = "{{#order.toString()}}", condition = "{{#condition == null}}")
    public boolean testCondition(Long orderId, Order order, String condition) {
        return false;
    }

2、使用对象 diff 功能

场景如下: 比较一个对象修改了什么字段内容。由 什么 变成了 什么

@LogRecord(success = "更新了订单{_DIFF{#oldOrder, #newOrder}}",
            type = LogRecordType.ORDER, bizNo = "{{#newOrder.orderNo}}",
            extra = "{{#newOrder.toString()}}")
    public boolean diff(Order oldOrder, Order newOrder) {

        return false;
    }

//  ----------  如果只传一个修改对象,则需要向 LogRecordContext 中 put 一个变量。可以为null
@LogRecord(success = "更新了订单{_DIFF{#newOrder}}",
            type = LogRecordType.ORDER, bizNo = "{{#newOrder.orderNo}}",
            extra = "{{#newOrder.toString()}}")
    @Override
    public boolean diff1(Order newOrder) {
        LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, null);
        return false;
    }

entity 信息

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
    @DiffLogField(name = "订单ID", function = "ORDER")
    private Long orderId;
    @DiffLogField(name = "订单号")
    private String orderNo;
    @DiffLogField(name = "创建时间")
    private Date createTime;
    @DiffLogField(name = "列表项", function = "ORDER")
    private List<String> items;
}

最后打印的内容:更新了订单 【列表项】添加了【xxxx(aaa)】删除了【xxxx(bbb)】;【订单ID】从【xxxx(99)】修改为【xxxx(88)】;【订单号】从【MT0000011】修改为【MT0000099】;

还支持:@DiffLogAllFields 注解。同时提供了 @DIffLogIgnore 注解来忽略字段

@Data
@DiffLogAllFields
public class Order {
    @DIffLogIgnore
    private Long orderId;
    private String orderNo;
    private Date createTime;
    private List<String> items;
}

最后打印的内容:更新了订单 【items】添加了【xxxx(aaa)】删除了【xxxx(bbb)】;【orderNo】从【MT0000011】修改为【MT0000099】;

标签:mzt,log,bizNo,private,biz,newOrder,日志,public
From: https://www.cnblogs.com/galenblog/p/18541172

相关文章

  • Logback 初篇
    知识体系        Logback的知识体系分为四部分。        第一部分,基础,模块,搭建环境,流程,配置文件各个配置项的含义。        第二部分,核心对象,logger,appender,encoder与Layout,filter。        第三部分,杂项,性能,MDC等。        第......
  • 第七届生物技术与生物医学国际学术会议(ICBB 2025) 2025 7th International Conference
    重要信息官网:https://ais.cn/u/vEbMBz......
  • Excel.Application使用手册(摘自:https://www.cnblogs.com/codingking/p/6484461.html)
    定制模块行为(1)OptionExplicit'强制对模块内所有变量进行声明  OptionPrivateModule'标记模块为私有,仅对同一工程中其它模块有用,在宏对话框中不显示  OptionCompareText'字符串不区分大小写  OptionBase1'指定数组的第一个下标为1(2)OnErrorResumeNe......
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.17——字符函数&&字符串函数
    文章目录1.字符函数1.1字符分类函数1.1.1islower1.2字符转换函数1.2.1tolower2.字符串函数2.1strlen2.2strcpy和strncpy2.3strcat和strncat2.4strcmp和strncmp2.5strstr2.6strtok2.7strerror希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的......
  • Cadence IC617为什么design库被识别成了Technology库,如何转换
    在我们设计电路过程中,经常建立工程,在本次设计电路过程中,得到别人给我的电路之后,一打开,电路不好使,元件库文件识别错了。相关联文件,才发现该文件已经被识别成Technology库了。这怎么办?这个问题好解决,你只要打开文件,看到文件下面有三个这样的文档,如下图。然后把图中画圈的位置......
  • 关于我,穿越异世界,凭c语言搅动风云vlog----利用数组进行大数相关计算
    关于我,穿越异世界,凭c语言搅动风云vlog----利用数组进行大数相关计算一.有关大数你应该要知道的那些事1.大数的概念我们一般将计算机基本数据类型无法存储的数称之为大数,本文涉及的大数均为整数,不包含小数。而且下文代码实现中的数组大小可根据需要修改。2.问题引入在c......
  • mysql清理binlog日志的方法
    MySQL中的binlog日志记录了数据库中数据的变动,便于对数据的基于时间点和基于位置的恢复,但是binlog也会日渐增大,占用很大的磁盘空间,因此,要对binlog使用正确安全的方法清理掉一部分没用的日志。 [方法一]手动清理binlog清理前的准备:1.查看主库和从库正在使用的binlog是哪个文件......
  • DataStudio连接opengauss报错Invalid username/password,login denied
    1、具体现象2、解决办法(1)密码不正确如果不确认密码是否正确可以重新修改密码,并进行gsql连接测试(2)修改参数确认密码正确,服务端可以正常连接,检查pg_hba.conf配置文件vim/opt/opengauss/data/single_node/ph_hba.conf此规则采用md5方式对密码加密两种解决方式:一种是......
  • 【项目实战】机器学习分类预测(RF/SVM/Logistic)与可解释性分析(SHAP/LIME)
    机器学习分类预测与SHAP可解释性分析研究目的今天,我将尝试预测一个人是否会中风。首先,我将进行广泛的数据可视化。这将帮助我了解是否有任何特征看起来预示着中风,或者实际上预示着不会中风。接下来,我将建立多个模型,并选出表现最好的一个。我将使用f1分数作为主要指标,因为......
  • InnoDB 存储引擎<六> Redo log
    目录关于RedoLog的一些其余问题小结本篇承接自InnoDB存储引擎<五>的内容InnoDB存储引擎<五>关于RedoLog的一些其余问题4.不同⽇志类型对应了哪些操作?分析过程:1.⽇志类型总体可以分为三⼤类,分别是:⽤于数据⻚的⽇志类型、⽤于表空间⽂件的⽇志类型和提供额外信......