Log4j, disable appenders dependent on environment
Asked Answered
E

3

13

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>
Elrod answered 4/1, 2013 at 10:58 Comment(1)
Is that you want to use the same file and achieve that? You can differentiate the log if you execute test cases and deployment. I think you have to manually change the file.Knorring
U
11

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>
Underskirt answered 4/1, 2013 at 12:21 Comment(2)
As a variation on this, you can always reference log4j.xml in the config but have your build process (Maven / Ant), copy log4j-production.xml to log4j.xml when creating the production JARs.Zion
I was aware this solution but I was wondering if there was another clever way to have just only one log4j.zml file rather then two to meet the requirements I had.Elrod
I
11

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.

Imperfection answered 21/11, 2014 at 21:23 Comment(1)
Works fine for me, avoid to add an other log4j file for production, thanksSimilar
D
0

With Log4j2 you could alternatively switch the appender reference with a Java system property like so:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
    <Appenders>
        <!-- Log file location uses Tomcat system variable, change for other web servers -->
        <RollingFile name="rolling-file"/>
        <Console name="console"/>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="${sys:log4j.loggers.root.appender:-rolling-file}"/>
        </Root>
    </Loggers>
</Configuration>

(the minus - in front of the default value in the sys prop variable is required for some reason)

To switch from the default "rolling-file" to the console"

-Dlog4j.loggers.root.appender=console
Dasilva answered 25/2, 2020 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.