diff --git a/readme.md b/readme.md index ac24ff46debe24d044c1145cea698e5a7917e202..36f5340234d7c1eced59bab6e024121c26b56608 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,8 @@ ## Change Log -2.0.0版本修改了一些变量名称,而且做的使向下不兼容的修改,如果大家不想改,可以一直使用1.x的版本,后续还会迭代的, 如果第一次接入推荐大家使用最新版本 3.X ~~ 1.x 文档: ./doc/document-1.x.md +2.0.0版本修改了一些变量名称,而且做的使向下不兼容的修改,如果大家不想改,可以一直使用1.x的版本,后续还会迭代的, 如果第一次接入推荐大家使用最新版本 3.X ~~ +1.x 文档: ./doc/document-1.x.md 修改点: @@ -49,7 +50,7 @@ io.github.mouzt bizlog-sdk - 3.0.3 + 3.0.3 ``` #### SpringBoot入口打开开关,添加 @EnableLogRecord 注解 @@ -73,7 +74,7 @@ public class Main { * success:方法调用成功后把 success 记录在日志的内容中 * SpEL 表达式:其中用双大括号包围起来的(例如:{{#order.purchaseName}})#order.purchaseName 是 SpEL表达式。Spring中支持的它都支持的。比如调用静态方法,三目表达式。SpEL 可以使用方法中的任何参数 -``` +```java @LogRecord( success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}", type = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}") @@ -91,7 +92,7 @@ public class Main { ###### 2. 期望记录失败的日志, 如果抛出异常则记录fail的日志,没有抛出记录 success 的日志。从 1.1.0-SNAPSHOT 版本开始,在LogRecord实体中添加了 fail 标志,可以通过这个标志区分方法是否执行成功了 -``` +```java @LogRecord( fail = "创建订单失败,失败原因:「{{#_errorMsg}}」", success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}", @@ -112,7 +113,7 @@ public class Main { 比如一个订单的操作日志,有些操作日志是用户自己操作的,有些操作是系统运营人员做了修改产生的操作日志,我们系统不希望把运营的操作日志暴露给用户看到, 但是运营期望可以看到用户的日志以及运营自己操作的日志,这些操作日志的bizNo都是订单号,所以为了扩展添加了子类型字段,主要是为了对日志做分类,查询方便,支持更多的业务。 -``` +```java @LogRecord( subType = "MANAGER_VIEW", success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}", @@ -131,7 +132,7 @@ public class Main { 如果一个操作修改了很多字段,但是success的日志模版里面防止过长不能把修改详情全部展示出来,这时候需要把修改的详情保存到 extra 字段, extra 是一个 String ,需要自己序列化。这里的 #order.toString() 是调用了 Order 的 toString() 方法。 如果保存 JSON,自己重写一下 Order 的 toString() 方法就可以。 -``` +```java @LogRecord( extra = "{{#order.toString()}}", success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}", @@ -148,7 +149,7 @@ public class Main { ###### 5. 如何指定操作日志的操作人是什么? 框架提供了两种方法 * 第一种:手工在LogRecord的注解上指定。这种需要方法参数上有operator -``` +```java @LogRecord( operator = "{{#currentUser}}", success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}", @@ -164,7 +165,7 @@ public class Main { * 第二种: 通过默认实现类来自动的获取操作人,由于在大部分web应用中当前的用户都是保存在一个线程上下文中的,所以每个注解都加一个operator获取操作人显得有些重复劳动,所以提供了一个扩展接口来获取操作人 框架提供了一个扩展接口,使用框架的业务可以 implements 这个接口自己实现获取当前用户的逻辑, 对于使用 Springboot 的只需要实现 IOperatorGetService 接口,然后把这个 Service 作为一个单例放到 Spring 的上下文中。使用 Spring Mvc 的就需要自己手工装配这些 bean 了。 -``` +```java @Configuration public class LogRecordConfiguration { @@ -206,7 +207,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { > !!!自定义函数 的参数 从 1.1.0 开始,从String 更改为了Object,老版本需要修改一下定义 -``` +```java // 没有使用自定义函数 @LogRecord(success = "更新了订单{{#orderId}},更新内容为....", type = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}", @@ -253,7 +254,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { ``` ###### 7. 日志文案调整 使用 SpEL 三目表达式 -``` +```java @LogRecord(type = LogRecordTypeConstant.CUSTOM_ATTRIBUTE, bizNo = "{{#businessLineId}}", success = "{{#disable ? '停用' : '启用'}}了自定义属性{ATTRIBUTE{#attributeId}}") public CustomAttributeVO disableAttribute(Long businessLineId, Long attributeId, boolean disable) { @@ -269,7 +270,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { 若想跨方法使用,可通过LogRecordContext.putGlobalVariable(variableName, Object) 放入上下文中,此优先级为最低,若方法上下文中存在相同的变量,则会覆盖 -``` +```java @Override @LogRecord( success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}", @@ -289,7 +290,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { 使用 LogRecordContext.putVariable(variableName, Object) 添加的变量除了可以在注解的 SpEL 表达式上使用,还可以在自定义函数中使用 这种方式比较复杂,下面例子中示意了列表的变化,比如 从[A,B,C] 改到 [B,D] 那么日志显示:「删除了A,增加了D」 -``` +```java @LogRecord(success = "{DIFF_LIST{'文档地址'}}", bizNo = "{{#id}}", prefix = REQUIREMENT) public void updateRequirementDocLink(String currentMisId, Long id, List docLinks) { RequirementDO requirementDO = getRequirementDOById(id); @@ -347,7 +348,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { 比如下面的例子:condition 变量为空的情况 才记录日志;condition 中的 SpEL 表达式必须是 bool 类型才生效。不配置 condition 默认日志都记录 -``` +```java @LogRecord(success = "更新了订单ORDER{#orderId}},更新内容为...", type = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}", detail = "{{#order.toString()}}", condition = "{{#condition == null}}") @@ -364,7 +365,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { __DIFF有重载的两种使用方式: 下面的例子。__DIFF 函数传递了两个参数,一个是修改之前的对象,一个是修改之后的对象 -``` +```java @LogRecord(success = "更新了订单{_DIFF{#oldOrder, #newOrder}}", type = LogRecordType.ORDER, bizNo = "{{#newOrder.orderNo}}", detail = "{{#newOrder.toString()}}") @@ -376,7 +377,7 @@ __DIFF有重载的两种使用方式: 下面的例子。__DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null -``` +```java @LogRecord(success = "更新了订单{_DIFF{#newOrder}}", type = LogRecordType.ORDER, bizNo = "{{#newOrder.orderNo}}", detail = "{{#newOrder.toString()}}") @@ -391,7 +392,7 @@ __DIFF有重载的两种使用方式: 下面给出了需要DIFF的对象的例子,需要在参与DIFF的对象上添加上 @DiffLogField 注解,name:是生成的 DIFF 文案中 Field 的中文, function: 跟前面提到的 function一样,例如可以把用户ID映射成用户姓名。 -``` +```java @Data @NoArgsConstructor @AllArgsConstructor @@ -422,7 +423,7 @@ public class Order { 看下源码中的 test 示例: -``` +```java @Test public void testDiff1() { Order order = new Order(); @@ -521,7 +522,7 @@ public class User { 源码中的 test 示例: -``` +```java @Test @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) public void diffUser() { @@ -565,7 +566,7 @@ public class User { 如果用户不想使用这样的文案怎么办呢? 可以在配置文件中配置:其中__fieldName是:字段名称的替换变量,其他内置替换变量可以看 LogRecordProperties 的源码注释 -``` +```yaml mzt: log: record: @@ -577,7 +578,7 @@ mzt: 用户可以自己实现 ILogRecordPerformanceMonitor 接口,实现对日志性能的监控。默认是 DefaultLogRecordPerformanceMonitor 需要开启 debug 才能打印日志 -``` +```yaml //开启debug方法: logging: level: @@ -597,7 +598,7 @@ ns % Task name 默认逻辑:被注解的方法不抛出异常会记录 success 的日志内容,抛出异常会记录 fail 的日志内容, 当指定了 successCondition 后 successCondition 表达式为true的时候才会记录 success内容,否则记录 fail 内容 -``` +```java @LogRecord(success = "更新成功了订单{ORDER{#orderId}},更新内容为...", fail = "更新失败了订单{ORDER{#orderId}},更新内容为...", type = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}", @@ -613,7 +614,7 @@ success内容,否则记录 fail 内容 默认日志记录错误不影响业务的流程,若希望日志记录过程如果出现异常,让业务逻辑也一起回滚,在 @EnableLogRecord 中 joinTransaction 属性设置为 true, 另外 @EnableTransactionManagement order 属性设置为0 (让事务的优先级在@EnableLogRecord之前) -``` +```java @EnableLogRecord(tenant = "com.mzt.test", joinTransaction = true) @EnableTransactionManagement(order = 0) public class Main { @@ -627,7 +628,7 @@ public class Main { ###### 15.方法记录多条日志 若希望一个方法记录多条日志,在方法上重复写两个注解即可,前提是两个注解**不相同** -``` +```java @LogRecord( subType = "MANAGER_VIEW", extra = "{{#order.toString()}}", success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}", @@ -646,7 +647,7 @@ public class Main { * 重写OperatorGetServiceImpl通过上下文获取用户的扩展,例子如下 -``` +```java @Service public class DefaultOperatorGetServiceImpl implements IOperatorGetService { @@ -661,7 +662,7 @@ public class DefaultOperatorGetServiceImpl implements IOperatorGetService { ``` * ILogRecordService 保存/查询日志的例子,使用者可以根据数据量保存到合适的存储介质上,比如保存在数据库/或者ES。自己实现保存和删除就可以了 > 也可以只实现保存的接口,毕竟已经保存在业务的存储上了,查询业务可以自己实现,不走 ILogRecordService 这个接口,毕竟产品经理会提一些千奇百怪的查询需求。 -``` +```java @Service public class DbLogRecordServiceImpl implements ILogRecordService { @@ -688,7 +689,7 @@ public class DbLogRecordServiceImpl implements ILogRecordService { } ``` * IParseFunction 自定义转换函数的接口,可以实现IParseFunction 实现对LogRecord注解中使用的函数扩展 例子: -``` +```java @Component public class UserParseFunction implements IParseFunction { private final Splitter splitter = Splitter.on(",").trimResults();