Question
Is it possible to make Log4J display the full path of the file it used for configuration?
Background
I have a love-hate relationship with log4j. In good times, it's great but when it's not working, it can be one of the most difficult things to debug. I manage all the logging in our application. As such, I'm very familiar with logging and the default initialization procedure defined in the manual. Still, it seems that, every few weeks, logging breaks and I spend a lot of time sorting out the problem.
This time, it's severely broken. Every single log statement everywhere is being dumped to the console and I can't figure out why. The same exact code base that used my log4j.xml files last week, is suddenly using some other configuration. Nothing obvious has changed. My only guess is, a few dependencies have changed and I suspect Maven has downloaded some evil JAR that's breaking everything.
If I could just figure out which configuration file Log4J decided to use at startup, I could tackle this and most other problems easily.
Summary
Is there some way to tell Log4J to print which file it used for configuration? Alternatively, is there a way to break a running application and use the debugger to answer this question (maybe with an expression or by inspecting variables)?
Yes, simply add log4j.debug
to the JVM system variables. For example:
java -Dlog4j.debug -cp ... some.class.name
Log4j will then output something like the following:
log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@1f7182c1.
log4j: Using URL [file:/C:/Users/matt/workspace/projectname/target/test-classes/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
log4j: System property is :null
log4j: Standard DocumentBuilderFactory search succeded.
log4j: DocumentBuilderFactory is: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: reset attribute= "false".
log4j: Threshold ="null".
...
For reference see the manual and the FAQ.
I am using Log4J2 and if you want to get the file from inside your Java Program this worked for me:
LoggerContext lContect = LogManager.getContext();
Field f = lContect.getClass().getDeclaredField("configuration");
f.setAccessible(true);
XmlConfiguration iWantThis = (XmlConfiguration) f.get(lContect);
System.out.println("Config File: " + iWantThis.getName());
The log4j 2 equivalent for this is to set <Configuration status="trace">
in the configuration file. This will display the location from where the log4j2 configuration file is loaded, as well as other internal details of the log4j2 configuration process. By default the status logger level is WARN, so you only see notifications when there is a problem.
If the configuration file is not found correctly, you can still enable log4j2 internal status logging by setting system property org.apache.logging.log4j.simplelog.StatusLogger.level
to TRACE
.