Using the BizLog SDK in Spring Boot: Configuration, Annotations, and Custom Extensions
This article introduces the BizLog SDK for Spring Boot, explains how to add the Maven dependency, enable the @EnableLogRecord switch, use @LogRecordAnnotation for various logging scenarios, customize operators, details, categories, and parse functions, and shows how to extend the framework with custom services and implementations.
Usage
Basic Usage
Maven Dependency
<dependency>
<groupId>io.github.mouzt</groupId>
<artifactId>bizlog-sdk</artifactId>
<version>1.0.4</version>
</dependency>SpringBoot Entry – Enable Switch
Add @EnableLogRecord annotation to the SpringBoot application class and optionally exclude the default datasource configuration:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableTransactionManagement
@EnableLogRecord(tenant = "com.mzt.test")
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}Log Recording
Define log templates with @LogRecordAnnotation . The template can include prefix , bizNo , success , fail , detail , category , and operator fields.
1. Simple success log
@LogRecordAnnotation(success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean createOrder(Order order) {
log.info("【创建订单】orderNo={}", order.getOrderNo());
// db insert order
return true;
}Resulting log example: "张三下了一个订单, 购买商品「超值优惠红烧肉套餐」, 下单结果: true".
2. Failure log
@LogRecordAnnotation(
fail = "创建订单失败,失败原因:「{{#_errorMsg}}」",
success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean createOrder(Order order) { ... }3. Category for operator distinction
@LogRecordAnnotation(
fail = "创建订单失败,失败原因:「{{#_errorMsg}}」",
category = "MANAGER",
success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean createOrder(Order order) { ... }4. Recording detailed information
@LogRecordAnnotation(
fail = "创建订单失败,失败原因:「{{#_errorMsg}}」",
category = "MANAGER_VIEW",
detail = "{{#order.toString()}}",
success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,下单结果:{{#_ret}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean createOrder(Order order) { ... }5. Specifying the operator
Two ways:
Manually set operator in the annotation (method must have a corresponding parameter).
Implement IOperatorGetService to obtain the current user automatically from thread context.
@Configuration
public class LogRecordConfiguration {
@Bean
public IOperatorGetService operatorGetService() {
return () -> Optional.of(OrgUserUtils.getCurrentUser())
.map(a -> new OperatorDO(a.getMisId()))
.orElseThrow(() -> new IllegalArgumentException("user is null"));
}
}6. Custom log text with functions
Define a custom parse function by implementing IParseFunction and register it as a Spring bean.
@Component
public class OrderParseFunction implements IParseFunction {
@Resource @Lazy private OrderQueryService orderQueryService;
@Override public String functionName() { return "ORDER"; }
@Override public String apply(String value) {
if (StringUtils.isEmpty(value)) return value;
Order order = orderQueryService.queryOrder(Long.parseLong(value));
return order.getProductName() + "(" + value + ")";
}
}7. Using SpEL ternary expressions
@LogRecordAnnotation(prefix = LogRecordTypeConstant.CUSTOM_ATTRIBUTE,
bizNo = "{{#businessLineId}}",
success = "{{#disable ? '停用' : '启用'}}了自定义属性{ATTRIBUTE{#attributeId}}")
public CustomAttributeVO disableAttribute(Long businessLineId, Long attributeId, boolean disable) { ... }8. Using external variables in templates
Put variables into LogRecordContext and reference them in the annotation.
@LogRecordAnnotation(success = "{{#order.purchaseName}}下了一个订单,购买商品「{{#order.productName}}」,测试变量「{{#innerOrder.productName}}」,下单结果:{{#_ret}}",
prefix = LogRecordType.ORDER, bizNo = "{{#order.orderNo}}")
public boolean createOrder(Order order) {
Order inner = new Order();
inner.setProductName("内部变量测试");
LogRecordContext.putVariable("innerOrder", inner);
return true;
}9. Diff list parsing function
Example of a function that compares old and new lists and generates a readable diff.
@Component
public class DiffListParseFunction implements IParseFunction {
@Override public String functionName() { return "DIFF_LIST"; }
@Override public String apply(String value) {
if (StringUtils.isBlank(value)) return value;
List
oldList = (List
) LogRecordContext.getVariable("oldList");
List
newList = (List
) LogRecordContext.getVariable("newList");
// compute added and deleted items and build result string
...
}
}Framework Extension Points
Override IOperatorGetService to customize operator retrieval.
Implement ILogRecordService to store logs in a database, Elasticsearch, etc.
Implement IParseFunction for custom placeholder functions (e.g., USER, ORDER).
Source Code
Repository: https://github.com/mouzt/mzt-biz-log
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.