我们有一个要求,每个日志都应该发送到 Activity MQ,从那里我们有一个监听器将审计数据保存到数据库中。 请为我提供一些如何使用 spring mvc 实现此要求的指导。
下面是我根据我对 log4j2 的一点了解可以想到的实现。
我已经阅读了 log4j2 文档,并使用以下命令实现了自定义日志级别“审核”。
java -cp log4j-core-2.5.jar org.apache.logging.log4j.core.tools.Generate$ExtendedLogger \
com.mycomp.AuditLogger AUDIT=350 > com/mycomp/AuditLogger.java
我还配置了 JMS 附加程序,如下所示,其中队列名称将驻留在 jndi.properties 中,如“queue.logQueue=queuename”
<Appenders>
<JMS name="jmsQueue" destinationBindingName="logQueue"
factoryName="org.apache.activemq.jndi.ActiveMQInitialContextFactory"
factoryBindingName="ConnectionFactory" providerURL="tcp://localhost:61616">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} %L ,%m] </pattern>
</PatternLayout>
</JMS>
</Appenders>
现在,当我们每次尝试像 log.audit("Some Debug message") 这样记录时,都必须将一条消息发送到队列,其中包含 Ipaddress、用户名、用户角色、方法名称和简单调试消息等信息。
下面的示例日志
016-04-22 14:32:12 DEBUG DemoServiceImpl 32 [ipAddress=166.32.457.87,username=xx123,userrole=admin] [invoking processDetails()]
016-04-22 14:32:12 DEBUG DemoServiceImpl 42 [ipAddress=166.32.457.87,username=xx123,userrole=admin] [invoking populateDetails()]
我正在使用下面的代码构建上面的日志消息
StringBuilder logmessage=new StringBuilder();
logmessage.append("[ipAddress=").append(logInfoDTO.getIpaddress())
.append(",username=").append(logInfoDTO.getUserName()).append(",userrole")
.append(logInfoDTO.getUserRole()).append("] [").append("invoking populateDetails()]");
log.audit(message);
我正在从 httpreq 、httpsession 对象捕获 Controller 中的一般信息(Ipaddress、用户名、用户角色),并将其设置在 DTO 对象中,并将其传递到所有层(服务、数据..)。
但这看起来不是一个有效的方法,请建议我一个更好的选择。
最佳答案
请参阅http://logging.apache.org/log4j/2.x/manual/eventlogging.html 。我建议的方法是将您始终希望出现在审核事件中的所有项目捕获到 servlet 过滤器或 Spring 请求拦截器中的 ThreadContext 中。那么您的“审核”事件只需要包含特定于正在发生的操作的元素。如果您利用 RFC 5424 布局,您最终可能会得到一个包含事件信息的结构化数据元素和另一个包含公共(public)信息的结构化数据元素。当然,您也可以将记录格式化为 JSON、XML 或您选择的任何其他格式。
这样做的一个好处是,您的所有诊断事件也将附加此数据,因此,如果您使用 Splunk 之类的工具,您将能够搜索仅包含这些属性的事件。
关于java - 使用 log4j2 和 JMS Appender 进行审计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36794135/