Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4j2 how to disable "date:" lookup - log4j throws exception

edit seems not to be possible at the moment filed an issue.


i am using log4j2 in my apache camel application. In camel file names can be configured this way "?fileName=${date:now:yyyyMMdd-HHmmss}ID.${id}.gz"

if i set log level to debug camel tries to log what it is doing but log4j seems to try to lookup/interpret the string with "date:" and throws an exception:

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)

Is there a way to turn off this "date:" lookup? Why does it try to interpret stuff coming from log at all? I think it should not be touched in any way?!

Edit, very easy to reproduce in test:

public class LogTest {

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

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

    }
}

It is crucial to us ${date:} - only "data:now" is working. So this problem is completely independent from camel, but camel uses ${date:...} pattern for several things. Here is a simple route that reproduces the problem - the exception will be thrown on camel set up phase - no test code needed - logging level must be "debug"!:

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");
            }
        };
    }

}
like image 560
dermoritz Avatar asked Nov 24 '14 11:11

dermoritz


People also ask

Can I disable log4j?

By default, log4j logging is used for all components for which logging information is generated. To disable log4j logging, set the logging level for the component to OFF in both log4j. conf and log4j.

What is JNDI lookup in log4j2?

Jndi Lookup The JndiLookup allows variables to be retrieved via JNDI. By default the key will be prefixed with java:comp/env/, however if the key contains a ":" no prefix will be added. <File name="Application" fileName="application.log">

What is Rootlogger in log4j2?

This concept is known as Logger Hierarchy. Logger Hierarchy is made up of set of LoggerConfig objects with a parent-child relationship. The topmost element in every Logger Hierarchy is the Root Logger. If Log4j2 doesn't find the configuration file, only Root Logger will be used for logging with logging level as ERROR.


2 Answers

This issue was fixed in 2.7 version of Log4j2.

The solution is to upgrade to that version (or higher) and add in the pattern attribute the option "{nolookups}" to %msg .

%msg{nolookups}

For example

<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{1} %L %M %t - %msg{nolookups}%n%xEx%n" />
like image 174
CookieSoup Avatar answered Oct 19 '22 05:10

CookieSoup


The problem can be avoided, if the simple-Expression is written as $simple{..} instead of ${..}. Then log4j2 won't use his Date-Lookup.

So, if you change your Route from:

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

to:

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

it should work, even if you debug Camel.

like image 26
StefanH Avatar answered Oct 19 '22 05:10

StefanH