Log4J2 - Write only to log file not console

Viewed 755

I am trying to write info to only log file not to console.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
 <Properties>
        <Property name="log-path">log</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingFile name="RollingFile" filename="log/logs.log"
            filepattern="${log-path}/$${date:yyyy-MM}/log-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
            <Policies>
                <SizeBasedTriggeringPolicy size="100MB" />
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <DefaultRolloverStrategy max="20" />
        </RollingFile>
 
    </Appenders>
    <Loggers>
            <Logger name="org.myapp." level="OFF" additivity="false"> 
            <AppenderRef ref="RollingFile"/> 
            <AppenderRef ref="Console"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingFile" />
        </Root>
        
    </Loggers>
</Configuration>

Above configuration neither print in console nor in log file, but I need to print the Logger.info into the log file and not in the console.

How to do this?

1 Answers

You have a couple of choices. First, you can add a level to the appender references:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
    <Property name="log-path">log</Property>
</Properties>
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <RollingFile name="RollingFile" filename="log/logs.log"
        filepattern="${log-path}/$${date:yyyy-MM}/log-%d{MM-dd-yyyy}-%i.log.gz">
        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
        <Policies>
            <SizeBasedTriggeringPolicy size="100MB" />
            <TimeBasedTriggeringPolicy/>
        </Policies>
        <DefaultRolloverStrategy max="20" />
    </RollingFile>
 
  </Appenders>
  <Loggers>
        <Logger name="org.myapp." level="trace" additivity="false"> 
        <AppenderRef ref="RollingFile" level="fatal"/> 
        <AppenderRef ref="Console" level="info"/>
    </Logger>
    <Root level="trace">
        <AppenderRef ref="Console" level="info"/>
        <AppenderRef ref="RollingFile" level="error"/>
    </Root>
    
    </Loggers>
</Configuration>

This allows the log events to pass through the Logger's filtering but then be allowed or rejected by the Appender references.

Another approach is to add filters to the Appenders

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
    <Property name="log-path">log</Property>
</Properties>
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <RollingFile name="RollingFile" filename="log/logs.log"
        filepattern="${log-path}/$${date:yyyy-MM}/log-%d{MM-dd-yyyy}-%i.log.gz">
        <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
        <Policies>
            <SizeBasedTriggeringPolicy size="100MB" />
            <TimeBasedTriggeringPolicy/>
        </Policies>
        <DefaultRolloverStrategy max="20" />
    </RollingFile>
 
  </Appenders>
  <Loggers>
        <Logger name="org.myapp." level="trace" additivity="false"> 
        <AppenderRef ref="RollingFile"/> 
        <AppenderRef ref="Console"/>
    </Logger>
    <Root level="trace">
        <AppenderRef ref="Console"/>
        <AppenderRef ref="RollingFile"/>
    </Root>
    
    </Loggers>
</Configuration>

In this case logging events are routed to the Appender and filtered there.

Note that when you use either of these configurations the tests Log4j performs to determine if logging is enabled will return true (since it is). That means you will be constructing lots of log events that may not get logged since Log4j doesn't know they won't be consumed by any appender.

Related