How to Build a Flexible Business Log System with Koala and MyBatis

This article introduces the ufind-businesslog framework, explains its improvements over the original Koala project, and provides step‑by‑step guidance on configuring annotations, Groovy log templates, thread pools, and custom exporters to achieve non‑intrusive, asynchronous business logging in Java applications.

Java Backend Technology
Java Backend Technology
Java Backend Technology
How to Build a Flexible Business Log System with Koala and MyBatis

Project Address

https://git.oschina.net/xuliugen/ufind-businesslog.git

Improvements

Removed dependencies on org.openkoala and org.dayatang.dddlib, allowing direct compilation.

Changed the way beans are obtained, solving the dependency removal issue.

Refactored project structure for clarity and added comments.

Enabled users to implement their own log exporter interface.

Added an admin system for log viewing, searching, modification, and deletion.

Provided a complete usage demo that records logs during user registration.

Switched from JPA to MyBatis.

Other minor fixes.

Business Log System Overview

1. Introduction

In many real‑world scenarios, business (or operation) logs are mixed directly with business logic, leading to tangled code. The Koala business log system separates business logic from logging.

// Create a company
public Organization createCompany(CompanyDto dto){
    // business logic
    companyDAO.save(dto);
    // record log
    LogDAO.save(new BusinessLog(userDAO.getSubjectName() + ",创建子公司:" + dto.getCompanyName()));
}

The result is a log entry such as "张三,创建子公司:广州子公司". Mixing logic and logging makes maintenance difficult.

2. Goals of the Koala Business Log System

Log recording should be minimally invasive to business methods.

Performance impact should be as low as possible (asynchronous implementation).

Configuration of system and log templates should be simple (based on Groovy).

Log persistence (export) should be flexible (interface‑based, supporting files, NoSQL, etc.).

Log templates can be modified without restarting the application.

True zero‑intrusion is impossible; a small annotation on the business method is required.

3. Module Division

ufind-businesslog-api – core API of the business log system.

ufind-businesslog-admin – backend management system for logs.

ufind-businesslog-demo – demo project illustrating usage.

4. Current Limitations

Depends on Spring AOP.

Only beans managed by the Spring IOC container can be logged.

5. How to Use the Default Koala Business Log Implementation

Outline

1. Add a businesslog.properties file to the classpath.
2. Annotate business methods with @BusinessLogAlias and set an alias.
3. Add a log template configuration file to the classpath.

5.1 Detailed Steps

(1) Add businesslog.properties to the classpath:

# Pointcut for business methods
pointcut=execution(* business.*Application.*(..))

# Enable logging
kaola.businesslog.enable=true

# Specify log exporter implementation (default includes BusinessLogConsoleExporter and BusinessLogExporterImpl)
businessLogExporter=com.ufind.businesslog.demo.exportImpl.BusinessLogExporterImpl

# Thread pool configuration (asynchronous export)
log.threadPool.corePoolSize=10
log.threadPool.maxPoolSize=50
log.threadPool.queueCapacity=1000
log.threadPool.keepAliveSeconds=300
log.threadPool.rejectedExecutionHandler=java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy

(2) If using the default exporter, configure database parameters in database.properties (MySQL example).

(3) Add an alias to a business method using @BusinessLogAlias, e.g.:

@BusinessLogAlias("UserInfoApplicationImpl_addUser")
public boolean addUser(UserInfo userInfo) {
    return this.userInfo.addUser(userInfo);
}

(4) Create a Groovy log template file (e.g., BusinessLogConfig.groovy) where each method name matches a business alias and returns a log string or a map with category and log text.

class BusinessLogConfig {
    def context
    def UserInfoApplicationImpl_addUser() {
        "${getPreTemplate()}:创建一个新用户:${context._param0.userAccount}"
    }
    def getPreTemplate() {
        "${context._user}-"
    }
}

5.2 Log Template Configuration

Single‑file configuration: place BusinessLogConfig.groovy in the classpath.

Multi‑file configuration: create a businessLogConfig folder and add any number of Groovy files; all .groovy files are loaded.

6. Implementing a Custom Log Exporter

Create a class that implements com.ufind.businesslog.api.BusinessLogExporter.

Configure the fully qualified class name in businesslog.properties (e.g.,

businessLogExporter=com.mycom.businesslog.MyBusinesslogExporter

).

Appendix: Accessing Context Variables in Log Templates

key                value
_methodReturn      Return value of the business method
_param0, _param1   Parameters of the business method
_executeError       Exception information if the method fails
_businessMethod     Business method name
_user               Operator of the business method
_time               Execution time
_ip                 IP address

ufind-businesslog Project Details

1. Core API (ufind-businesslog-api) includes:

BusinessLogAlias – annotation for business methods.

BusinessLogExporter – interface for custom log persistence.

BusinessLogInterceptor – intercepts method execution and triggers log generation.

BusinessLogThread – asynchronous thread that saves logs via the exporter.

BusinessLogServletFilter – filter that adds contextual information (user, IP) before request handling.

2. Demo project (ufind-businesslog-demo) shows how to implement a custom exporter.

3. Admin project (ufind-businesslog-admin) provides a Spring MVC + MyBatis UI for querying and managing logs stored in MySQL.

Main Workflow

LogFilter adds user and IP information to a ThreadLocal context.

Methods annotated with @BusinessLogAlias are intercepted after execution.

The interceptor determines the corresponding Groovy method name from the alias.

A BusinessLogThread is created to run the log export asynchronously.

The Groovy template method is invoked, returning the log text (or a map).

The configured exporter saves the log to the desired destination.

For a complete view, download the project and examine the source code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

loggingMyBatisspring-aopGroovybusiness log
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.