我正在为我的 Spring 启动应用程序构建审核日志。我想在数据库中跟踪对我的 Web 服务器的每个 POST 请求(甚至是失败)。我的审核代码使我的控制器变得混乱。有人可以建议一个适当的设计模式,使其干净,通用和可维护。
@JsonView(View.Student.class)
@PostMapping("/updateStudent")
public Student updateStudent(@Valid @RequestBody final Student studentConfig) {
Student oldStudentDefn =
repository.findById(studentConfig.getStudentId())
.map(Function.identity()).orElse(null);
final AuditBuilder builder = aAuditBuilder().withAction("UPDATE")
.withSource("GUI")
.withBeforeObj(oldStudentDefn)
.withAfterObj(studentConfig);
try{
if(repository.save(studentConfig)) {
builder.withStatus("Success");
} else {
throw new ApplicationException(" Student Save failed");
}
}catch(ApplicationException e) {
builder.withStatus("Failure");
throw e;
}
finally {
auditService.save(builder.build());
}
}
我想以这样的方式重构它,即每个端点的这个重复的 try-catch 构建器都转到一个公共服务,并且它足够通用,可以接受任何类型的对象,以便即使是教师、部分、进度报告等端点也可以通过调用相同的服务进行审核,但它不应该有任何代码重复。
使用 Spring Boot,您很可能嵌入了一个 servlet 容器。与其自己开发此功能,不如使用 servlet 容器工具,例如 Tomcat 具有可通过 AccessLogValve
配置的访问日志。输出日志文件,然后转换并导入到数据库中就足够了。
如果您需要更实时的解决方案,您可以查看像Jaeger或Micrometer这样的监控库。
关键是,除非您有非常具体的要求,否则有比编写自己的代码更简单的方法可以获得此功能。
基于Karol的出色回应(https://stackoverflow.com/a/54160447/8231165),我还建议使用现有的框架来满足你的需求。
一个例子是通过 Logstash 追加器/编码器为日志回传日志,然后通过 ELK 堆栈存储/操作它们(更多细节在这里:https://www.baeldung.com/java-application-logs-to-elastic-stack)。Logstash 有一个丰富的输出插件列表,例如 MongoDB 的一个。
另一种选择是将日志事件发布到消息代理(如 RabbitMQ),然后让使用者执行任何需要的操作,以便将这些事件存储在数据库中。
附带说明一下,所有 try-catch-finally 代码都可以放在一个不同的方法中(也许在 Util 类中)。