不要在该奋斗的年纪选择了安逸;|

黎华扬

园龄:8年1个月粉丝:4关注:3

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

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】;

本文作者:黎华扬

本文链接:https://www.cnblogs.com/galenblog/p/18541172

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   黎华扬  阅读(489)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起