log4j2 如何禁用“日期:”查找 - log4j 抛出异常

der*_*itz 3 apache-camel log4j2

目前似乎无法编辑提交问题


我在我的 apache 骆驼应用程序中使用 log4j2。在骆驼文件名可以这样配置"?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz"

如果我将日志级别设置为调试camel 尝试记录它正在执行的操作但log4j 似乎尝试使用“date:”查找/解释字符串并抛出异常:

2014-11-24 11:29:19,218 ERROR Invalid date format: "now:yyyyMMdd-HHmmss", using default java.lang.IllegalArgumentExcepti
on: Illegal pattern character 'n'
        at java.text.SimpleDateFormat.compile(Unknown Source)
        at java.text.SimpleDateFormat.initialize(Unknown Source)
        at java.text.SimpleDateFormat.<init>(Unknown Source)
        at java.text.SimpleDateFormat.<init>(Unknown Source)
        at org.apache.logging.log4j.core.lookup.DateLookup.formatDate(DateLookup.java:60)
        at org.apache.logging.log4j.core.lookup.DateLookup.lookup(DateLookup.java:53)
        at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:144)
        at org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1008)
        at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:926)
        at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:816)
        at org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:385)
        at org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:71)
        at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:36)
        at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:189)
        at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:53)
        at org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:52)
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:
104)
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:97)
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:428)
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:407)
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:365)
        at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:112)
        at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1347)
        at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1312)
        at org.apache.logging.slf4j.Log4jLogger.debug(Log4jLogger.java:132)
        at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:518)
        at org.apache.camel.util.IntrospectionSupport.setProperty(IntrospectionSupport.java:570)
        at org.apache.camel.util.IntrospectionSupport.setProperties(IntrospectionSupport.java:454)
        at org.apache.camel.util.EndpointHelper.setProperties(EndpointHelper.java:249)
        at org.apache.camel.impl.DefaultComponent.setProperties(DefaultComponent.java:272)
        at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:67)
        at org.apache.camel.component.file.GenericFileComponent.createEndpoint(GenericFileComponent.java:37)
        at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:123)
        at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:514)
        at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:547)
Run Code Online (Sandbox Code Playgroud)

有没有办法关闭这个“日期:”查找?为什么它试图解释来自日志的东西?我认为它不应该以任何方式触摸?!

编辑,在测试中很容易重现:

public class LogTest {

    private Logger log = LoggerFactory.getLogger(LogTest.class);

    @Test
    public void test() {
        log.info("${date:now:buhu}");

    }
}
Run Code Online (Sandbox Code Playgroud)

这对我们至关重要 ${date:} - 只有 "data:now" 有效。所以这个问题完全独立于 camel,但骆驼使用 ${date:...} 模式来处理几件事。这是重现问题的简单路线 - 将在骆驼设置阶段抛出异常 - 不需要测试代码 -日志记录级别必须为“调试”!:

public class LogTest extends CamelTestSupport{

    private Logger log = LoggerFactory.getLogger(LogTest.class);

    @Test
    public void test() {
        //log.info("${date:now:yyyyMMdd-HHmmss}");

    }

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {

            @Override
            public void configure() throws Exception {
                from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
            }
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

小智 5

如果将 simple-Expression 写成$simple{..}而不是,则可以避免该问题${..}。然后 log4j2 不会使用他的 Date-Lookup。

所以,如果你改变你的路线:

from("direct:a").to("file:./?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz"); 
Run Code Online (Sandbox Code Playgroud)

到:

from("direct:a").to("file:./?fileName=$simple{date:now:yyyyMMdd-HHmmss}ID.${id}.gz");
Run Code Online (Sandbox Code Playgroud)

即使您调试 Camel,它也应该可以工作。


小智 5

此问题在 Log4j2 2.7 版本中已修复。

解决方案是升级到该版本(或更高版本),并在模式属性中将选项“{nolookups}”添加到 %msg 。

%msg{nolookups}
Run Code Online (Sandbox Code Playgroud)

例如

<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1} %L %M %t - %msg{nolookups}%n%xEx%n" />
Run Code Online (Sandbox Code Playgroud)