繁体   English   中英

如何在登录文件之前使用Log4j2 xml重写追加程序修改LogEvent

[英]How to use Log4j2 xml Rewrite appender for modifying LogEvent before it logs in file

我想在log4j2.xml文件中使用重写追加程序,以便在记录之前可以修改日志。 我没有从Google获得太多帮助。 根据log4j2文档,Rewrite是具有重写方法的接口,而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>

解决方案1:使用RewriteAppender

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

如果您使用自己的Rewriter实现,则可以使其生效。

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

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

解决方案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 因此,我们不再去侦听和操纵它们,而是直接前往源代码并在此处进行工作。

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

祝好运! 玩得开心!

MapRewritePolicy将评估包含MapMessage的LogEvent,并添加或更新Map的元素。 仅当您的应用程序调用logger.info(new MapMessage(keyValueMap))此方法才有效。 我怀疑这不是您的应用程序当前正在执行的操作。

通常,您的消息将是SimpleMessage(如果您调用logger.info("Just a string without parameters") )或ParameterizedMessage(如果您将其称为logger.info("Hi {}!", name) )。 RewriteAppender将无法对SimpleMessage或ParameterizedMessages进行任何操作,因此什么也不会被替换...

您可能需要看一下PatternLayout的文档:如果您使用replace{pattern}{regex}{substitution}模式,它可以用一些替换值替换字符串消息中的replace{pattern}{regex}{substitution}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM