Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j, disable appenders dependent on environment

I would like to have one log4j.xml config and be able to log to console while developing my application. Once deployed to an environment I want to only log to a file appender and not the console. How can I achieve this?

This is my current config:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="DEBUG" />
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{dd-MM-yyyy HH:mm:ss} %-5p%c{1} - %m%n" />
        </layout>
    </appender>

    <appender name="LogFileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="${log-base-dir}/${adapter-name}.log" />
        <param name="MaxFileSize" value="5000KB" />
        <param name="MaxBackupIndex" value="99" />
        <param name="append" value="true" />        
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{dd-MM-yyyy HH:mm:ss} %-5p%c{1} - %m%n" />
        </layout>
    </appender>

    <root>
        <level value="info" />
        <appender-ref ref="ConsoleAppender" />
        <appender-ref ref="LogFileAppender" />
    </root>

</log4j:configuration>
like image 988
Ash Avatar asked Jan 04 '13 10:01

Ash


2 Answers

One of the solutions could be separation of log4j configuration files for development and production environments e.g.:

  • log4j-development.xml - for development environment
  • log4j-production.xml - for production environment

Then your application startup command could have parrameter specifying log4j configuration file e.g. java -Dlog4jconfig=log4j-development.xml -jar Application.jar

You can configure log4j by getting value of log4jconfig property in your code e.g. System.getProperty("log4jconfig").

Pros of that solution are as follows:

  • You can specify loggers independently (ConsoleAppender and LogFileAppender in development and only LogFileAppender in production)
  • You can specify your logging level per environment (e.g. error in production and debug in development)
  • You can configure file logger independently e.g. keep logs for X days in production (for audit purposes etc.) and have only one log file in development etc.

That pattern is used in many application servers where you have multiple environments (Development, UAT, Staging, Production etc.)

Example of log4j-development.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="DEBUG" />
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{dd-MM-yyyy HH:mm:ss} %-5p%c{1} - %m%n" />
        </layout>
    </appender>

    <root>
        <level value="debug" />
        <appender-ref ref="ConsoleAppender" />
    </root>

</log4j:configuration>

Example of log4j-production.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="LogFileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="${log-base-dir}/${adapter-name}.log" />
        <param name="MaxFileSize" value="5000KB" />
        <param name="MaxBackupIndex" value="99" />
        <param name="append" value="true" />        
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{dd-MM-yyyy HH:mm:ss} %-5p%c{1} - %m%n" />
        </layout>
    </appender>

    <root>
        <level value="error" />
        <appender-ref ref="LogFileAppender" />
    </root>

</log4j:configuration>
like image 122
Tom Avatar answered Sep 18 '22 14:09

Tom


It is easy to do using appender's Threshold parameter and JVM system property. E.g.

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
    <param name="Threshold" value="${my.console.level}" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %-5p [%c{1}] %m%n" />
    </layout>
</appender>

Then when starting application on prod use -Dmy.console.level=OFF

At the same time when starting locally use -Dmy.console.level=ALL

Both OFF and ALL are valid log4j levels.

like image 27
dpetruha Avatar answered Sep 21 '22 14:09

dpetruha