17

How does Log4j manages multiple log4j.properties in its classpath? Which log4j.properties file takes precedence? Let me describe the exact scenario.

I have multiple maven modules developed by different teams and each one of them has its own log4j.properties file. All of these log4j.properties file have RootLogger configured along with ConsoleAppender and FileAppenders.

Now, when Log4j loads which log4j.properties file will it use to configure the RootLogger settings ? Also, how will Log4j create the Logger hierarchy ? How will the log4j.properties file in other 3rd party jars affect the logging process ?

cosmos
  • 2,414
  • 4
  • 23
  • 25

2 Answers2

16

The first file in the classpath will be loaded. So if A.jar and B.jar both contain a file, and A.jar comes before B.jar in the classpath, A.jar's file will be loaded. That's how the class loader works.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I have a specific requirement If I want to load both the properties file how can I achive it ? I mean log4j.properties files from both a.jar and b.jar should be loaded...Is there any way ?? – GKP Sep 15 '13 at 15:03
  • Why would you need to load them both? The goal of externalizing the configuration to a file is to be able to configure the logging the way you want to. So the jar files shouldn't even come with a log4j.xml file bundled. Instead, they should document which loggers they use (by convention, the logger name is the class name), and then the application assembler, using both jar files, would create its own config file, containing the configuration for all the libraries used in the application. – JB Nizet Sep 15 '13 at 16:27
  • I want load both of them because I am writing a client api where I want to log the client api specific logs to a separate file. the app can have it's own log4j config but i don't want the client side to change anything. I will just give them the api jar where the api specific appender and logger will be defined. Also note that I don't want to achieve it programatically I want to do it by configuration. – GKP Sep 15 '13 at 19:29
  • 1
    Then you should tell the client what to add to their own log4j config file to get logs from your library. Bundling a log4j config file in your jar will only make them mad, because your config could get loaded instead of theirs. Let the client have the control. – JB Nizet Sep 15 '13 at 21:01
  • I am aware of this option but I was thinking if any other way available for this ..Thanks for your suggestion !! – GKP Sep 16 '13 at 15:08
  • I provide A.jar to my client, and my client will have it's own log4j property file, Do I have a way that these two config will be merged? And if there are some conflics, my client's config will over mine. – JaskeyLam Sep 08 '16 at 09:52
6

log4j ver 1.x:

As others have stated, log4j looks for the first configuration file in the classpath. See: http://logging.apache.org/log4j/1.2/manual.html

But when there are both 'log4j.xml' and 'log4j.properties' files in the classpath, it seems from experimentation that log4j gives precedence to 'log4j.xml' over 'log4j.properties'.

i.e. First, log4j seems to look in the classpath for the first 'log4j.xml' file. If there is none, then log4j seems to then look in the classpath for the first 'log4j.properties' file.

Copying and pasting from the code below may help in determining what configuration file is being used:

import org.apache.log4j.Logger;

public class TestLog4j
{

  static
  {
    System.out.println("Classpath: [" + System.getProperty( "java.class.path" ) + "]" );
    System.out.println("Found logging configuration files:");
    System.out.println("  log4j.xml: " + Logger.getRootLogger().getClass().getResource( "/log4j.xml" ) );
    System.out.println("  log4j.properties: " + Logger.getRootLogger().getClass().getResource( "/log4j.properties" ) );
  }

  public static void main(String[] args)
  {
    System.out.println("main():");
  }
}

Edit:

log4j ver 2.x:

The search order for the default configuration file is documented here: http://logging.apache.org/log4j/2.x/manual/configuration.html

i.e. For log4j version 2.x, if no higher precedence configuration file is found (e.g. log4j2-test.[properties | yaml | json | xml]) then the file log4j2.properties is used if found in the classpath. Note that log4j2.xml has the lowest precedence, and will be used only if log4j2 'properties', 'yaml' or 'json' configuration files are all not found.

Note: To aid in debugging log4j configuration issues, set the 'log4j.debug' property, e.g. with:

java -Dlog4j.debug ... 

See also: How to initialize log4j properly?

Kieron Hardy
  • 731
  • 7
  • 8
  • looks like it's the other way round? refer [link] (https://logging.apache.org/log4j/2.x/manual/configuration.html) – chandra_cst Jun 13 '17 at 00:41
  • Answer edited to reflect log4j ver 2.x, adding link to documentation (thanks @chandra_cst) and additional debugging hint. – Kieron Hardy Jun 14 '17 at 23:53