gpt4 book ai didi

java - 如何使用 Log4j2 xml Rewrite appender 在登录文件之前修改 LogEvent

转载 作者:数据小太阳 更新时间:2023-10-29 02:57:08 27 4
gpt4 key购买 nike

我想在我的 log4j2.xml 文件中使用 Rewrite appender,以便在记录之前我可以修改日志。我没有从谷歌那里得到太多帮助。根据 log4j2 文档,Rewrite 是一个具有重写方法的接口(interface),而 MapRewritePolicy 是实现类,当我运行它时,我能够看到我的 web3.log 文件生成但没有看到日志内容中的任何修改。我看到了 MapRewritePolicy 源代码并在我的项目中创建了本地实现类 MapRewritePolicyImpl.java 并放置了一些 System.out 以查看代码流是从 log4j2.xml 文件进入此类的。我已修改我的 log4j2.xml 以使用 MapRewritePolicyImpl.java,但代码流未进入我的 MapRewritePolicyImpl.java 类。

<Rewrite name="rewrite" >
<Appender-Ref ref="web3" />
<MapRewritePolicyImpl">
<KeyValuePair key="creditCard" value="new12345"/>
</MapRewritePolicyImpl>
</Rewrite>



<Configuration monitorInterval="5" status="debug" strict="true">
<Appenders>
<RollingFile name="web3" fileName="../logs/web3.log"
filePattern="${sys:catalina.home}/logs/$${date:yyyy-MM-dd}/web3-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout
pattern="%d{dd/MM/yyyy HH:mm:ss,SSS} [%X{cartID}] [%X{sessionId}] [%p] [%t] [%c] (%F:%L) - %m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
<SizeBasedTriggeringPolicy size="10 MB" />

</Policies>
</RollingFile>
<Rewrite name="rewrite" >
<Appender-Ref ref="web3" />
<MapRewritePolicy">
<KeyValuePair key="creditCard" value="new12345"/>
</MapRewritePolicy>
</Rewrite>
</Appenders>
<Loggers>
<Logger name="com.virginamerica" level="info" additivity="false">
<!-- <Appender-Ref ref="web3" /> -->
<Appender-Ref ref="rewrite"/>
</Logger>
</Loggers>
</Configuration>

最佳答案

解决方案一:使用 RewriteAppender

您的示例似乎几乎是正确的。正如@Remko Popma 所提到的,您选择的 Rewrite 实现不适合您的用例。

如果您使用自己的 Rewriter 实现,您可以让它工作。

我在这里找到了一个很好的例子: RewriteAppender Example

该示例包含 log4j2.xml 和 RewriteAppender 的实现。在 RewriteAppender(此处称为 MarkerInjectorRewritePolicy)中,您可以修改事件以满足您的需要。在示例中,作者注入(inject)了一些标记数据,您不需要该部分。

.

解决方案 2:使用 LogEventFactory

解决方案 1 有一些缺点。假设您有 100 个记录器和 50 个 Appender。尝试实现解决方案 1 现在您最终得到另外 50 个 RewriteAppender 声明以及对所有记录器的调整以使用重定向记录器而不是实际的目标 Appender。这可能非常乏味且容易出错。

一个更简单的解决方案是:

// Do this somewhere before using the logger
System.setProperty(Constants.LOG4J_LOG_EVENT_FACTORY, MyLogEventFactory.class.getName());

或者通过start参数设置:

-DLog4jLogEventFactory=my.package.MyLogEventFactory

编辑: 更好:设置它的更可靠的方法是使用 log4j2.component.properties:

  • 创建一个名为 log4j2.component.properties 的文本文件并将其放入您的类路径中。
  • 将此代码放入其中:Log4jLogEventFactory = my.package.MyLogEventFactory

该文件由log4j自动加载,用于配置多个核心设置。使用此文件,您不必每次都传递启动参数,而且您也不会遇到类初始化排序问题的潜在问题(例如使用 System.setProperty() 时)。

LogEventFactory 实现非常简单:

public class MyLogEventFactory implements LogEventFactory {

@Override
public LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message message,
List<Property> properties, Throwable t) {
{ // In my case i wanted "log.error(new Exception(msg))"
// to pass the exception properly to the event,
// as if "log.error(msg, new Exception(msg))" was called.
if (t == null && message instanceof ObjectMessage) {
ObjectMessage msg = (ObjectMessage) message;
t = msg.getThrowable();
}
}
// XXX do your adjustments here
return new Log4jLogEvent(loggerName, marker, fqcn, level, message, properties, t);
}

}

LogEventFactory 用于创建LogEvents。因此,我们不是在以后拦截和操纵它们,而是简单地找到源头并在这里完成我们的工作。

有了这个我们就得到了所有的事件!

祝你好运!玩得开心!

关于java - 如何使用 Log4j2 xml Rewrite appender 在登录文件之前修改 LogEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22218832/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com