跨层创建数据以编写审计日志

时间:2017-02-21 14:39:03

标签: java tomcat cross-cutting-concerns

背景

有问题的应用程序是部署在Tomcat中的Java Web应用程序,它使用Apache CXF来公开REST服务。我找到了Spring配置,但不确定它与CXF基础设施的连接情况。

每当重要事件发生时,如实体被更新或删除,我想记录信息,包括(但不限于):

  1. 发生了什么
  2. 提出请求的人
  3. 更改了哪个实体
  4. 实体的新状态(如适用)
  5. 有关发送的任何通知电子邮件的信息
  6. 等...
  7. 当前设置&挑战

    我们有几个图层,调用看起来像这样:控制器>服务>数据层> Utils(电子邮件,短信发送等)。

    问题是,我想要收集和记录的数据开始可用,并且仅在单独的层中可用。有时数据会通过参数传递到下一层,但有时则不传递,因为其他层不需要数据。以下是一些例子:

    • 某些与HTTP请求相关的数据仅用于某些验证,不会发送到服务层。
    • 有时,核心实体数据仅在服务和数据层中可用,并且对控制器不可用。
    • Utils的各个层生成一些任何其他层都不知道的最终数据(如链接,代码,最终电子邮件内容)。

    但我需要从所有图层中收集此类信息并将其作为单个日志行记录以供审核。

    约束

    • 在尊重图层边界方面,代码设计得不好。所以,有时事情会在不应该的地方传递。但我无法继续这样做。
    • 我无法将所有必需的数据返回给控制器,最后将其记录在那里,因为中间层'方法在很多地方被调用,并且不可能重构它们。
    • 我不能将它们分别记录在不同的地方,因为要求不允许这样做。如果没有其他任何方式,我可以推动这个策略,并有一个共同的请求ID或一些东西和多个日志行,以关联它们。

    我的问题是,我应该如何以及在何处收集所有这些数据并将其写入审核日志?在Java Web应用程序中执行上述操作的最佳实践是什么?

1 个答案:

答案 0 :(得分:0)

听起来你的申请很乱。

但是,只要根据请求触发所有内容,它仍然可以执行此操作。

以下是两种方法:

1)使用Logback等日志框架中的MDC对象。可以使用键在请求的基础上填充此对象,您可以在其中附加可以在以后提取以进行日志记录的任意信息(或者可以将其作为附加字段自动附加到日志消息中)。请在此处阅读:https://logback.qos.ch/manual/mdc.html

这将是我推荐的解决方案,因为它与您要实现的目标非常匹配。如果那是不可能的话:

2)创建一个对ThreadLocal具有静态访问权限的对象,用于跟踪各个层的信息。请求完成后,将其记录在HTTP过滤器中。并确保再次清除信息,以免与使用相同线程的下一个请求混淆。

如果您不想使用审核日志记录污染代码,可以考虑使用Aspects(面向方面​​编程)将此功能添加到您的类中。