Where to put the logback.xml file in Tomcat when we want to have it configurable?
And how to make it accessible for the Java application(s) running inside?
You typically want to have logback.xml on the classpath. Per the Logback FAQ:
For web-applications, configuration files can be placed directly under WEB-INF/classes/.
You therefore need to put it in:
/webapps/your-app/WEB-INF/classes/
Logback has some conventions for where it looks for it. Those are documented here.
Logback tries to find a file called logback.groovy in the classpath.
If no such file is found, logback tries to find a file called logback-test.xml in the classpath.
If no such file is found, it checks for the file logback.xml in the classpath..
If neither file is found, logback configures itself automatically using the BasicConfigurator which will cause logging output to be
directed to the console.
But you can also tell it where to find the file.
You may specify the location of the default configuration file with a
system property named "logback.configurationFile". The value of this
property can be a URL, a resource on the class path or a path to a
file external to the application.
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
Note that the file extension must be ".xml" or ".groovy". Other
extensions are ignored. Explicitly registering a status listener may
help debugging issues locating the configuration file.
Related
We have a webapp that contains two log4j2.xml files:
one within WEB-INF/classes containing webapp-specific logging settings (1), and
one within the root directory of a dependency located in WEB-INF/lib containing default logging settings that we use also in other webapps (2)
My questions are:
How does tomcat read and evaluate these files?
In which order are they read?
Is it possible to overwrite settings of (2) by (1) and how would I do that?
Thank you.
Reading the documentation here you will find that:
Log4j allows the configuration file to be specified in web.xml using the log4jConfiguration context parameter. Log4j will search for configuration files by:
If a location is provided it will be searched for as a servlet context resource. For example, if log4jConfiguration contains "logging.xml" then Log4j will look for a file with that name in the root directory of the web application.
If no location is defined Log4j will search for a file that starts with "log4j2" in the WEB-INF directory. If more than one file is found, and if a file that starts with "log4j2-name" is present, where name is the name of the web application, then it will be used. Otherwise the first file will be used.
The "normal" search sequence using the classpath and file URLs will be used to locate the configuration file.
if I understand correctly, this answers all your questions.
I have several classes within a package and several packages within my project.
For those files that are inherited, within the parent class is
{ // File location for log4j2.xml
System.setProperty("log4j.configurationFile",
"file:\\\\" + System.getProperty("user.dir") + "\\Properties\\log4j2.xml");
}
And yet, I see ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
So, obviously, once isn't enough.
So what is the general rule that I need to set the system property of log4j.configurationFile?
Once per package?
Once per class?
Each parent/base class, regardless of the package?
Or something else?
What's best practice for multiple classes and packages?
Log4j 2 configures itself on initialisation i.e. whenever a Logger instance is first created within an instance of a JVM, approximately ... the first class in your application which declares a Logger instance causes Log4j 2 to initialise itself. So, the answer to this question ...
How often do you need to set the configuration file for log4j2?
... is once.
The issue reported in your OP: No log4j2 configuration file found. Using default configuration is caused by Log4j being unable to find the configuration file you attempted to point it at. This issue is not caused by not 'setting the configuration file' often enough.
According to the docs Log4j will look for its configuration source as follows:
Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt to load the configuration using the
ConfigurationFactory that matches the file extension.
If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.
If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.
If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.
If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.
If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.
If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the
classpath.
If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.
If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.
If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.
If your attempt to set log4j.configurationFile was successful then option 1 would be engaged but that attempt is not successful, we know this because the error message you quote tells us that Log4j is falling through to option 10.
I would suggest running your application with -Dlog4j.configurationFile=/path/to/log4j2.xml or ensuring that the log4j2.xml is on your application's classpath. The idea of littering your code with System.setProperty(...) calls feels like an anti pattern and is likely to be quite brittle since any static Logger which is instanced before the System.setProperty(...) call will result in Log4j initialising itself before it knows about your config file location.
I have an ear deployed in weblogic with the log4j2.xml logPath set as
<Property name="logPath">some_path_1<Property>
and a logger defined as
<Logger name="a.b.c.d" level="INFO" />
Inside this ear/lib there is a jar containing a log4j2.xml and the logPath property is defined as
<Property name="logPath">some_path_2<Property>
and a logger with a very similar packaging structure
<Logger name="a.b.c" level="INFO" />
Both log4j2.xml's are configured to have a different log file name as well.
But the logs for both are coming in the path some_path_2 and with the file name defined in that jar
How to ensure both logging outputs happens separately as defined?
My ear structure is like
ear
|--lib
|--|--abc.jar
|--|--|--log4j2.xml //the one thats getting loaded
|--xyz.war
|--|--WEB-INF
|--|--|--classes
|--|--|--|--log4j2.xml // the one I want
Edit1: I added the following in the containing war's web.xml but it did not help
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j2.xml</param-value>
</context-param>
Edit2: I also tried this and found that this is working intermittently
ear
|--lib
|--|--abc.jar
|--|--|--log4j2.xml //the one thats getting loaded
|--|--xyz.jar
|--|--|--log4j2.xml //the one I want.. works but not always.Does classloader loads the jars alphabetically?
|--xyz.war
|--|--WEB-INF
|--|--|--classes
|--|--|--|--log4j2.xml // the one I want
Log4j is initialized only once by using the configuration file which is first found by the log4j bootstrapper. All other (possible present) configuration files will not be taken into account. Learn more on the precedences of log4j auto configuration in the appropriate tutorials.
As you probally already know your problem is that only one configuration-file gets loaded and which one depends on the classloader. So you should not rely on that.
There are only two possible soulutions for your problem, but today I do not have the time to work it out for you - sorry. You have to remove or rename the config-file in abc.jar
Remove log4j2.xml from abc.jar
Do it with your build-script in ANT/MAVEN/GRADLE or whatever. Copy-paste the interessting parts of the config-file in your config-file.
Rename log4j2.xml inside abc.jar
Do it with your build-script in ANT/MAVEN/GRADLE or whatever. Now you could include the whole config-file in your log4j2.xml. This is called CompositeConfiguration.
I hope this little advice will help you.
Good luck!
Can you remove the XMLs from the jar/war and use only one xml file at the ear level which has details of both the logging paths/properties. You can try to reconfigure log4j2 in code with a specific configuration file.
You can also dynamically write to separate log files, but I personally haven't tried this so I wouldn't be able to guide more on this.
Are you sure you want to use "log4.xml" file to be use by log4j2. I don't think, log4j2 automatic configuration mechanism try to find out configuration file with name "logj.xml".
From official documentation,
Log4j has the ability to automatically configure itself during
initialization. When Log4j starts it will locate all the
ConfigurationFactory plugins and arrange them in weighted order from
highest to lowest. As delivered, Log4j contains four
ConfigurationFactory implementations: one for JSON, one for YAML, one
for properties, and one for XML.
Log4j will inspect the "log4j.configurationFile" system property and,
if set, will attempt to load the configuration using the
ConfigurationFactory that matches the file extension.
If no system property is set the properties ConfigurationFactory will look for log4j2.properties or log4j2.json or log4j2.xml files in classpath.
Possibly you should try to rename the file "xyz.war//WEB-INF/classes/log4j.xml" to "xyz.war//WEB-INF/classes/log4j2.xml". Obviously content of this file must confirm to log4j configuration xsd.
i would like to turn of my debug statements at runtime in log4j2. According to the documentation we can do this. I kept my log4j.xml file in default package and then made jar out of it. Since I cannot modify jar i specified xml file using Dlog4j.configuration=/path/to/log4j.xml. However,this is not working. I Tried everything using file:// uri to all the combination, still it is not picking the xml.
The system property to specify the config file location is different from log4j-1.x.
In log4j2, the property is "log4j.configurationFile".
So if the config is in a jar file you would use:
-Dlog4j.configurationFile=jar:file:///C:/path/to/jarfile.jar!/path/to/log4j2.xml
(I assume you have the monitorInterval set in your configuration as documented here: http://logging.apache.org/log4j/2.x/manual/configuration.html#AutomaticReconfiguration)
Following must be added to configuration file:
<Configuration monitorInterval="60" >
Is it possible to add or override log4j configuration previously loaded by log4j.xml file with another log4j.xml file loaded at runtime ?
My Glassfish server loads at startup log4j.xml file and I would like to change this configuration with another log4j.xml file in EAR file.
I tried to use DOMConfigurator.configure("log4j.xml") but it seems that the previously configuration is not overrided (but this method find log4j.xml file because when I change to non existing file, I have Exception).
How can I do this please ?
A log4j Configurator always applies its configuration starting from the "current" settings. If you want the new settings to replace the old ones, simply call LogManager.resetConfiguration() first, before calling the DOMConfigurator.