在 Spring boot Java 中记录每个请求的恰当设计模式



我正在为我的 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 类中)。

最新更新