log4j2 logging happening in the wrong path - java

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.

Related

How often do you need to set the configuration file for log4j2?

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.

Where to put logback.xml in Tomcat?

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.

how to change configuration file of log4j2 at runtime?

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" >

override log4j configuration with another log4j.xml file

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.

tomcat, 2 webapps, 2 log4js, but both apps log to one file

To elaborate on that, I have a Tomcat server version 7.0.27 running Java 1.6.0_27.
I have two wars, each with their own log4j jar, also using slf4j with slf4j-log4j. Each war has it's own configuration file (log4j.xml).
war 1 should use file log-1.log and war 2 should use file log-2.log but both are logging into log-1.log.
I've checked there are no other log4j jars in the tomcat installation so I'm not sure where the problem is. I've also turned off shared class loading but that made no difference. My next step is to turn on verbose class loader logging and/or start debugging log4j but maybe someone here knows why this is and can save me some time. Thanks for any input on this.
Update:
Ok think I got this one. The log4j xml files are fine. After doing a verbose:class I can see that log4j.jar is only getting loaded once and from neither web application.
I'm working with Documentum. They have a runtime jar required to use their libraries that is an empty jar with a manifest file. The manifest points to a bunch of jars. In other words, they don't use maven... Anyway ... one of those jars happens to be logj4 found in the Documentum installation. So it seems both webapps are using that one. I think this is the problem. To be confirmed...
If you are placing Documentum's runtime jar on your top-level classpath, and that runtime jar is referencing log4j.jar, then it will only load once. You don't have to use that runtime jar, though, or you can use it in just your Documentum .war, if one is non-Documentum.
You didn't post your properties file but i can think of some reasons:
You don't have an appender that writes to the different files, i.e you need appender1 to write to log1.log and appender2 writing to log2.txt
You have the appenders set up right but both the applications are using the same logger, so they both write to the same file.
You have 2 loggers, each with its own appender, but in your code you are not initializing the correct logger:
//there is no logger called com.sample, so it defaults to root logger that has appender that writes to log1.txt
Logger logger = Logger.getLogger(com.sample.MyClass.class);
If you post your properties file and your logger init code it'll be easier to help you.

Categories