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

news/2024/11/14 5:05:28/文章来源:https://www.cnblogs.com/galenblog/p/18541172

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 {@Autowiredprivate 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);}@Overridepublic List<LogRecord> queryLog(String bizKey, Collection<String> types) {return Lists.newArrayList();}@Overridepublic 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 {@Overridepublic 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()}}")@Overridepublic 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 {@DIffLogIgnoreprivate Long orderId;private String orderNo;private Date createTime;private List<String> items;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/832175.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Django 5 By Example》阅读笔记:p17-p53

《Django 5 By Example》学习第2天,p17-p53总结,总计37页。 一、技术总结 1.数据库迁移 python manage.py makemigrations blog python manage.py sqlmigrate blog 0001 python manage.py migrate 2.ORM Django自带ORM。 3.view (1)定义 p42, A Django view is just a Python…

CentOS虚拟机无法查看ipv4地址

CentOS默认没有开启ens33 vi /etc/sysconfig/network-scripts/ifcfg-ens33将最后一行的ONBOOT=no修改为ONBOOT=yes 重启网卡服务 systemctl restart network然后 ip addr 查看ip目前这个是动态ip 如果要静态ip 继续编辑网卡配置文件ifcfg-ens33,将BOOTPROTO=dhcp修改为BOOTPRO…

人工智能是这样理解“情绪”的

前一篇:《人工智能模型训练:从不同格式文件中读取训练数据集》 前言:在前面的内容中,我们经常提到“特征”,那么如何表示特征呢?举个例子,在日常生活中,我们描述一个快递包装盒时可能会提到它的高度、宽度和深度(这三个值就是盒子的特征,当然也可以用颜色、重量、材料…

利用卷积神经网络(CNN)进行花朵分类任务

一、卷积神经网络 卷积神经网络(Convolutional Neural Netword,CNN)是一种深度学习模型,它在图像识别、视频分析、自然语言处理等领域表现出色。CNN 的核心思想是利用卷积运算来提取输入数据的特征,并且能够保持空间层次结构。 卷积神经网络的架构如下:我们今天的重点是利…

南沙C++信奥赛老师解一本通题 1385:团伙(group)

​ 【题目描述】在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1、我朋友的朋友是我的朋友; 2、我敌人的敌人是我的朋友; 所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这…

Docker:部署kkFileView所有格式文档在线预览服务

前言 kkFileView是一个文档在线预览服务,基本支持主流文档格式预览,目前支持的文件类型如下:支持 doc, docx, xls, xlsx, xlsm, ppt, pptx, csv, tsv, dotm, xlt, xltm, dot, dotx,xlam, xla 等 Office 办公文档 支持 wps, dps, et, ett, wpt 等国产 WPS Office 办公文档 支…

学校厕所防欺凌检测系统

学校厕所防欺凌检测系统通过在关键区域安装的音频和视频监控设备,学校厕所防欺凌检测系统实时捕捉现场的声音和画面。AI音频分析技术能够对前端音频进行实时处理,当系统识别到“救命”、“打架”、“老师快来”等敏感词汇时,会自动触发预警机制,联动值班老师或校园安全中心…

物流园区烟火烟雾检测系统

物流园区烟火烟雾检测系统通过在园区关键位置安装的高清摄像头,物流园区烟火烟雾检测系统实现对监控区域的无人值守和不间断工作。系统利用先进的AI视觉算法,能够主动发现监控区域内的烟雾和火灾苗头,并进行实时分析报警。与传统的火灾监测系统相比,该系统不需要依赖其他传…

错误代码的个人见解以及逻辑分析题

一、代码错误分析代码中的错误: 1.src 指针指向字符串字面值,不可修改: 字符串 "hello,world" 是存储在只读区域的常量字符串,不能通过指针直接修改。 如果需要倒序操作,需要把字符串复制到一个可修改的内存中。2.dest 未正确分配内存: 在 malloc(len) 时,没有…

docx 生成word报告

# -*- coding: utf-8 -*- import base64 import os from io import BytesIO from docx import Document from docx.shared import Inches, Pt from bs4 import BeautifulSoup from matplotlib import pyplot as plt from wordcloud import WordCloud # 设置全局字体 plt.rcPara…

leetcode算法题-有效的括号(简单)

有效的括号(简单) leetcode:https://leetcode.cn/problems/valid-parentheses/description/ 前言 防止脑袋生锈,做一下leetcode的简单算法题,难得也做不来哈哈。 大佬绕道,小白可看。 题目描述 给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符…

30+企业高管齐聚!医疗器械企业渠道优化与健康增长主题沙龙成功举办

10月29日,深圳医疗器械行业协会携手纷享销客,共同举办了一场以“渠道优化与健康增长”为主题,探索医疗器械企业在新形势下渠道管理及落地实践的沙龙活动。此次活动吸引了33位医疗器械企业的管理层,共同探寻医疗器械企业营销增长的新思路、新渠道与新路径。<活动照片>…