Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure log4j to log different log levels to different files for the same logger

People also ask

What is the correct hierarchy of log levels order in log4j logging?

Below is the log4j logging level order. Trace < Debug < Info < Warn < Error < Fatal.


What you need to do is have a single <logger> definition with a defined level of INFO, but in your two appender definitions, you set their thresholds accordingly, e.g.

<appender name="ERROR_FILE">
   <param name="Threshold" value="ERROR"/>
</appender>

<appender name="GENERAL">
   <param name="Threshold" value="INFO"/>
</appender>

You then add both appenders to your logger:

<logger name="com.acme">
  <level value="INFO"/>
  <appender-ref ref="ERROR_FILE"/>
  <appender-ref ref="GENERAL"/>
</logger>

Log entries now going to the logger will get sent to both appenders, but since they have different independent thresholds, the ERROR_FILE appender will only log ERROR and above.


Full working solution including the date in the filename:

<appender name="InfoFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
      <param name="FileNamePattern" value="/var/output/Info_%d{ddMMyyyy}.log" />
    </rollingPolicy>
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d{HH:mm:ss} %-5p %t %c{2} - %m%n" />
    </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
      <param name="levelMin" value="INFO" />
      <param name="levelMax" value="INFO" />
    </filter>
</appender>

<appender name="ErrorFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">
    <param name="Threshold" value="ERROR" />
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
        <param name="FileNamePattern" value="/var/output/Error_%d{ddMMyyyy}.log" />
    </rollingPolicy>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{HH:mm:ss} %-5p %t %c{2} - %m%n" />
    </layout>
</appender>
<root>
    <level value="INFO" />
    <appender-ref ref="InfoFileAppender" />
    <appender-ref ref="ErrorFileAppender" />
</root>

You need to use log4j filters:

<filter class="org.apache.log4j.varia.LevelRangeFilter">
    <param name="levelMin" value="ERROR" />
    <param name="levelMax" value="ERROR" />
</filter>

That way you can create log files for each level separately.


If you are using log4j2 and config with XML format, ThresholdFilter is a good solution.

Here is a sample:

    <?xml version="1.0" encoding="UTF-8"?>

      <Configuration status="WARN">

       <Appenders>
          <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout>
        <Pattern>%d %-5p  %m%n</Pattern>
      </PatternLayout>
      <ThresholdFilter level="DEBUG"/>
    </Console>
    
    <RollingFile name="RollingDebugLogFile" fileName="logs/app-debug.log" filePattern="logs/$${date:yyyy-MM}/app-debug-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %-5p  %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="20MB"/>
      </Policies>
      <ThresholdFilter level="DEBUG"/>
    </RollingFile>
  
    <RollingFile name="RollingErrorLogFile" fileName="logs/app-error.log" filePattern="logs/$${date:yyyy-MM}/app-error-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %-5p  %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="20MB"/>
      </Policies>
      <ThresholdFilter level="ERROR"/>
    </RollingFile>
  
    <RollingFile name="RollingInfoLogFile" fileName="logs/app-info.log" filePattern="logs/$${date:yyyy-MM}/app-info-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %-5p  %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="20MB"/>
      </Policies>
      <ThresholdFilter level="INFO"/>
    </RollingFile>
    
  </Appenders>

  <Loggers>
    <Logger name="testLogger" level="DEBUG" additivity="false">
        <AppenderRef ref = "Console" />
        <AppenderRef ref="RollingErrorLogFile" />
        <AppenderRef ref="RollingInfoLogFile" />
        <AppenderRef ref="RollingDebugLogFile" />
    </Logger>
    <Root level="INFO">
      <AppenderRef ref = "Console" />
      <AppenderRef ref="RollingErrorLogFile" />
      <AppenderRef ref="RollingInfoLogFile" />
      <AppenderRef ref="RollingDebugLogFile" />
    </Root>
    
  </Loggers>
</Configuration>

Well, actually, you can do it using .properties file; you don't have to use .xml file :

  • Log only WARN

    log4j.appender.appenderName.filter.a=org.apache.log4j.varia.LevelRangeFilter
    log4j.appender.appenderName.filter.a.LevelMin=WARN
    log4j.appender.appenderName.filter.a.LevelMax=WARN
    
  • Log from INFO to WARN

    log4j.appender.appenderName.filter.a=org.apache.log4j.varia.LevelRangeFilter
    log4j.appender.appenderName.filter.a.LevelMin=INFO
    log4j.appender.appenderName.filter.a.LevelMax=WARN