Java 跨层收集数据以编写审核日志
背景 所讨论的应用程序是部署在Tomcat中的Java web应用程序,它使用Apache CXF公开REST服务。我找到了Spring配置,但不确定它与CXF基础架构的连接情况如何 每次发生重要事件时,如实体被更新或删除,我都会记录信息,包括(但不限于):Java 跨层收集数据以编写审核日志,java,tomcat,cross-cutting-concerns,Java,Tomcat,Cross Cutting Concerns,背景 所讨论的应用程序是部署在Tomcat中的Java web应用程序,它使用Apache CXF公开REST服务。我找到了Spring配置,但不确定它与CXF基础架构的连接情况如何 每次发生重要事件时,如实体被更新或删除,我都会记录信息,包括(但不限于): 发生了什么事 是谁提出这个要求的 改变了什么实体 实体的新状态(如适用) 有关发送的任何通知电子邮件的信息 等等 当前设置和挑战 我们有几个层,调用如下所示:控制器>服务>数据层>UTIL(电子邮件、短信发送等) 问题是,我想要收集和记录的
- 一些与HTTP请求相关的数据仅用于某些验证,不会发送到服务层
- 有时,核心实体数据仅在服务层和数据层中可用,控制器不可用
- UTIL的各个层生成一些其他层都不知道的最终数据片段(如链接、代码、最终电子邮件内容)
- 该规范在尊重层边界方面设计得不好。所以,有时候事情是在不应该的地方传递的。但我不能继续这样做了
- 我无法将所有必需的数据返回到控制器,并最终将它们记录在那里,因为中间层的方法在很多地方都被调用,并且不可能将它们全部重构
- 我不能将它们分别记录在不同的地方,因为要求不允许这样做。如果没有其他方法,我可以推动这个策略,使用一个公共请求ID或其他东西,以及多个日志行,来关联它们
我的问题是,我应该如何以及在哪里收集所有这些数据并将它们写入审核日志?在Java web应用程序中执行上述操作的最佳实践是什么?听起来您的应用程序一团糟 但是,只要所有内容都是基于请求触发的,就应该仍然可以这样做 这里有两种方法: 1) 从Logback这样的日志框架中使用MDC对象。可以根据请求使用键填充此对象,您可以在其中附加任意信息,这些信息可在以后提取用于日志记录(也可以自动附加为日志消息的附加字段)。请在此阅读: 这将是我推荐的解决方案,因为它与您试图实现的目标非常匹配。如果不可能,那么: 2) 创建一个对ThreadLocal具有静态访问权限的对象,该对象用于跟踪跨各个层的信息。当请求完成时,将其记录在HTTP筛选器中。并确保再次清除该信息,以免与使用同一线程的下一个请求混淆
如果你不想用审计日志来污染你的代码,你可以考虑使用方面(面向方面的编程)来将这些功能添加到你的类。
你可以写日志“建议”用于审计目的。@ Jun16164MDC看起来对我来说是可行的。我的担忧有两个方面。1) 使用线程池的UTIL—MDC有关于它的文档。2) 最新的servlet规范异步请求内容导致线程工作的方式。我不完全知道,但我需要弄清楚我是否必须考虑到这一点。您如何看待后者?您是否使用新的异步请求?只有当代码自愿放弃它所运行的线程,然后稍后继续处理请求时,才真正使用它。如果您的代码更传统,每个请求一个线程,那么您不会有任何问题。@john16384不,不会。我只是想知道它的效果,以防将来我们开始使用异步。MDC现在看来是应该走的路。MDC不知道异步servlet请求。为了使其适用于异步线程,您必须再次使用类似于过滤器(Spring中的AsyncHandlerInterceptor)的东西,在释放请求线程时存储MDC数据,然后在继续相同请求时再次设置它。这不应该是不可能的。