Project1 is using classes from project2 and project3.
Project 2 and project 3 has seperate log4j.properties file and logging classes (Pro2.java & Pro3.java with info,debug methods) in their src folder.
Project1 has a main method that calls
Pro2.logInfo("This is a log for project2");
Pro3.logInfo("This is a log for project3");
I want these logs to be logged in two seperate log files as I set in their log4j.properties file.
In general, you can only have one active log4j.properties file (there are exceptions in J2EE environments).
what you want to do, is configure the logging for both projects in a single properties file. You'd need to define two appenders, and specify the categories for each project to use their own appender.
Log4j will automatically look for and use config files it finds on the classpath. It looks for files called log4j.properties and log4j.properties and possibly others.
Alternatively you can programatically load config using;
String filename = "/path/to/config/Project1log4j.properties";
PropertyConfigurator.configure(filename);
Related
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'm using the log4j2 library to manage the logging process.
I created a configuration file named log4j2.xml containing the Appenders and Loggers configurations. Then, I defined a Logger in each class
private static Logger my_logger = LogManager.getLogger(my_class);
I did not specify anywhere the name of the conf file, so I think that the library implicitly get and read it.
Now, I need to provide my application in the form of a jar file, so I need to make the config file available so that the user can modify and configure it.
In my case, I suggest to create a XXX folder at the level of the jar file, containing all the configuration files used by my app.
My question is how can I say to the app "get XXX/log4j2.xml" rather than the xml contained into the jar.
that config file must be located in the class path, if you want the app to read the configuration from any other location then you need to specify that using
PropertyConfigurator.configure("/myPath/log4j.properties");
Make any folder and put your property or xml file in that. In order to read the property file you can do something like this:
Properties objProperties = new Properties();
<your-class>.class.getClassLoader().getResource("folder/log4j.properties");
objProperties.load(isFile);
or, Also this:
InputStream ist = Thread.currentThread().getContextClassLoader().getResourceAsStream("folder/log4j.properties");
In case of java web application please use the link
I had a similar task a few weeks ago.
I solved it this way:
Store a template of your log4j2.xml inside your jar files resource folder
When running your application, check for a file named log4j2.xml in the jar files current directory
If there is one, use that to create your logger
If not, copy your template from within your jar to the jar files directory and then use that to create your logger.
Cheers
I have a war file which is deployed on jboss server. This war contains some jar files.
What i need is to create seperate logs for different jars.
I am using log4j for logging purpose and also intergrated log4j properties file in each jar.
My log4j for every jar have different paths.
Still the logs are generated in server.log of jboss.
I need help to generate seperate logs for every jar.
If you want to make different log file for different jar, you will have to configure it in your log4j.properties file related to every jar(I assume that every jar have different package naming convention).
Here is an example like if you want to log message in different file whose package name starts with org.jar1 and org.jar2.
log4j.debug=true
log4j.logger.org.jar1=DEBUG,jar1logger
log4j.logger.org.jar2=DEBUG,jar2logger
log4j.additivity.org.jar1=false
log4j.additivity.org.jar2=false
log4j.appender.jar1logger=org.apache.log4j.RollingFileAppender
log4j.appender.jar1logger.layout=org.apache.log4j.PatternLayout
log4j.appender.jar1logger.layout.ConversionPattern=%d [%t]<%-5p> %c -> %m%n
log4j.appender.jar1logger.File=/var/log/mylog/jar1.log
log4j.appender.jar1logger.Append=true
log4j.appender.jar1logger.MaxFileSize=1024KB
log4j.appender.jar1logger.MaxBackupIndex=5
log4j.appender.jar2logger=org.apache.log4j.RollingFileAppender
log4j.appender.jar2logger.layout=org.apache.log4j.PatternLayout
log4j.appender.jar2logger.layout.ConversionPattern=%d [%t]<%-5p> %c -> %m%n
log4j.appender.jar2logger.File=/var/log/mylog/jar2.log
log4j.appender.jar2logger.Append=true
log4j.appender.jar2logger.MaxFileSize=1024KB
log4j.appender.jar2logger.MaxBackupIndex=5
Based on your requirement whether you want to create log on daily basis or on size basis you have to change your configuration.
Keep in mind if any jar whose package name in any jars start with org.jar1 then all logs will be written into jar1.log 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.
My procedure for using log4j is this:
put a .properties file somewhere in a project folder
in an initialization method, that runs only once, invoke PropertyConfigurator.configure("path_to_file")
in every method we need to use logger we define a static logger variable and simply invoke getLogger(class)
Is this correct?
What happens if the initialization module is not defined? Where can I put the "log4j.properties" file such that I don't have to invoke propertyconfigurator.configure at all? If that's not possible, is it OK to invoke PropertyConfigurator.configure("path_to_file") in every method that uses a logger?
If you put it somewhere in the classpath, Log4J will automatically load it. A typical place for it is the source (or resource) root directory. That way it can get copied into the root directory of your jar too (if you create one from your class files).
The exact details for this depend on what build system you use. E.g. in Maven the convention is to put it in src/main/resources.
The default initialization procedure for log4j is documented in this section of the log4j tutorial. This explains in detail the steps that log4j takes to locate the logging configuration.
The simplest way to configure log4j is to put a the properties file somewhere that allows it to be found by the class loader using the name "/log4j.properties". There are other approaches that you can use as well that involve setting system properties, loading the properties file programmatically, or even instantiating the Loggers, Appenders and so on via the log4j APIs. (Not that the latter is a good idea ...)
(Putting the log4j properties file in "src/main/resources" in a Maven project is just one of a number of possible ways to get the file into your application's classpath root.)