How the Operation Log Aspect Captures Requests and Responses in ContiNew Admin
The ContiNew Admin operation log aspect uses an AOP interceptor from the ContiNew-Starter-Log module to automatically capture HTTP requests and responses by wrapping annotated controller methods, storing the data in thread-local LogRecord objects, and persisting them via LogDaoLocalImpl to the sys_log table.
The continew-org/continew-admin repository implements automatic operation logging through a clean aspect-oriented architecture. By leveraging the external ContiNew-Starter-Log dependency combined with a local persistence implementation, the system records full request-response cycles without cluttering business logic.
How the Operation Log Aspect Works
The logging mechanism relies on the LogAspect class provided by the continew-starter-log Maven dependency. This aspect intercepts any controller method marked with the @Log annotation, creating a complete audit trail through three distinct phases.
Intercepting Methods with the @Log Annotation
Controllers declare logging requirements through the @Log annotation imported from top.continew.starter.log.annotation.Log. In continew-system/src/main/java/top/continew/admin/system/controller/LogController.java at line 39, methods like list() use @Log(module = "系统日志") to trigger interception, while the exportOperationLog method uses @Log(ignore = true) to skip logging for high-volume export endpoints.
Capturing Request Data Before Execution
Before the target method executes, the aspect constructs a LogRequest object containing the HTTP method, URI, query parameters, request body, and current user details. This data is stored in a thread-local LogRecord context, ensuring isolation between concurrent requests.
Recording Responses and Exceptions
After method completion—whether successful or exceptional—the aspect builds a LogResponse object capturing the HTTP status code, response body, and execution duration. The aspect updates the existing LogRecord with this response data, creating a complete entry ready for persistence.
Persisting Operation Logs to the Database
The concrete persistence logic resides in continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java (lines 75-154). This bean implements the LogDao interface and handles the final database write.
Converting LogRecord to LogDO
The LogDaoLocalImpl#add(LogRecord) method transforms the aspect's LogRecord into a LogDO entity defined in continew-system/src/main/java/top/continew/admin/system/model/entity/LogDO.java. The implementation extracts request metadata from LogRequest and response details from LogResponse, setting the type field to LogTypeEnum.OPERATION for operation-specific logs.
Database Storage via MyBatis-Plus
The converted LogDO entity is inserted into the sys_log table using LogMapper from continew-system/src/main/java/top/continew/admin/system/mapper/LogMapper.java. This MyBatis-Plus mapper handles the actual SQL execution, storing fields including request method, URI, status code, response body, and execution time.
Key Source Files and Components
LogController.java– Demonstrates@Logannotation usage on REST endpoints.LogDaoLocalImpl.java– Concrete implementation that persistsLogRecordobjects to the database (lines 75-154).LogDO.java– Entity class mapping thesys_logdatabase table.LogMapper.java– MyBatis-Plus mapper interface for database operations.LogServiceImpl.java– ContainsexportOperationLogmethod for Excel export functionality.LogAspect– Provided by the external starter module; handles AOP interception andLogRecordassembly.
Implementation Examples
Annotating Controller Methods
@RestController
@RequestMapping("/system/log")
public class LogController {
@Log(module = "系统日志")
@SaCheckPermission("monitor:log:list")
@GetMapping("/list")
public PageResult<LogResp> list(@Valid LogQuery query, @Valid SortQuery sort) {
return baseService.list(query, sort);
}
@Log(ignore = true) // Skip logging for exports
@GetMapping("/export/operation")
public void exportOperationLog(@Valid LogQuery query,
@Valid SortQuery sortQuery,
HttpServletResponse response) {
baseService.exportOperationLog(query, sortQuery, response);
}
}
Aspect Execution Flow
@Aspect
@Component
public class LogAspect {
@Around("@annotation(logAnnotation)")
public Object around(ProceedingJoinPoint pjp, Log logAnnotation) throws Throwable {
// Build LogRequest from HttpServletRequest
LogRequest request = LogRequestBuilder.build();
// Execute target method
Object result = pjp.proceed();
// Build LogResponse with status and timing
LogResponse response = LogResponseBuilder.build();
// Assemble and persist LogRecord
LogRecord record = new LogRecord()
.setRequest(request)
.setResponse(response)
.setModule(logAnnotation.module())
.setIgnore(logAnnotation.ignore());
logDao.add(record);
return result;
}
}
Persistence Layer Implementation
@Component
public class LogDaoLocalImpl implements LogDao {
private final LogMapper logMapper;
@Override
public void add(LogRecord logRecord) {
LogDO logDO = new LogDO();
// Copy request data
LogRequest req = logRecord.getRequest();
logDO.setRequestMethod(req.getMethod());
logDO.setRequestUri(req.getUri());
// Copy response data
LogResponse resp = logRecord.getResponse();
logDO.setStatus(resp.getStatus());
logDO.setResponseBody(resp.getBody());
// Mark as operation type log
logDO.setType(LogTypeEnum.OPERATION);
// Insert to database
logMapper.insert(logDO);
}
}
Summary
- The ContiNew-Starter-Log module provides the
LogAspectthat intercepts@Logannotated methods. - LogRequest and LogResponse objects capture complete HTTP request and response data in a thread-local context.
- LogDaoLocalImpl in
continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.javahandles the conversion fromLogRecordtoLogDOand persists to thesys_logtable. - The @Log annotation supports configuration options like
modulenaming andignoreflags to control logging behavior. - Operation logs are automatically categorized with
LogTypeEnum.OPERATIONfor proper filtering and export viaLogServiceImpl.exportOperationLog.
Frequently Asked Questions
What triggers the operation log aspect in ContiNew Admin?
The aspect triggers when a controller method is annotated with @Log from top.continew.starter.log.annotation.Log. The LogAspect class from the ContiNew-Starter-Log dependency uses Spring AOP to wrap these methods, executing advice before and after the method invocation to capture request and response data.
How does the operation log aspect handle concurrent requests?
The aspect stores log data in a thread-local LogRecord context, ensuring that each HTTP request maintains isolated logging state. This prevents cross-thread contamination when multiple users simultaneously access annotated endpoints, maintaining accurate request-to-response correlation for each individual thread.
Where is the operation log data physically stored?
The LogDaoLocalImpl class in continew-server/src/main/java/top/continew/admin/config/log/LogDaoLocalImpl.java persists logs to the sys_log database table via MyBatis-Plus. This implementation converts the aspect's LogRecord into LogDO entities, setting the type to LogTypeEnum.OPERATION before insertion through LogMapper.
Can I disable operation logging for specific endpoints?
Yes. The @Log annotation accepts an ignore parameter that bypasses the logging aspect when set to true. For example, in LogController.java, the exportOperationLog method uses @Log(ignore = true) to prevent generating log entries during large data exports, reducing database overhead for high-volume operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →