logging 2 web apps to 2 different files - log4j

I have 2 web applications built from the same source tree within tomcat, which each use a PropertyConfigurator loading their respective /webapp/WEB-INF/classes/log4j.properties.
Currently tomcat is configured to use one console appender for the whole container, and both app's log4js just write to the console:
log4j.rootCategory=info, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
This means I end up with one big catalina.out for the whole container.
I would like to configure each of the applications log4js so that they append to their own separate rolling files.
I'm aware I can use system properties substitution within log4j.properties however isn't system properties shared across the VM and therefore not threadsafe between the 2 applications within the container?
Can someone suggest a tidy solution which allows me to configure the 2 applications to log to separate files, preferably with the application's context name within the log's file name.
thanks, p.

Where is your log4j.jar and commons-logging.jar placed in tomcat directory? And which version of tomcat you are using?
If you have one copy of these jar inside common/lib than surely catalina.log would be used by all logging since tomcat's log4j.properties file is only the one getting configured for both server and webapps under it.
Assuming this scenario holds valid in your case, copy log4j.jar and common-logging.jar under WEB-INF/lib for both web applications.
For using application name within log's file name, since separate log4j.properties file is used for each application, name your logfiles as you like in log4j.properties file against FileAppender or RollingFileAppender.

Related

How to read level changes from log4j.xml when application is running

I am running a executable jar file, which logs using log4j.xml(version 1.2).
Whenever i change the log level in the xml file, i have to restart the java application for the new log level to reflect.
Can i add some configuration in the log4j.xml so that new log level will be taken into account without application restart?
Thanks,
-Venkat
Log4j 1.x has reached end of life on August 5, 2015. So I would like to recommend you to use log4j 2.x which supports this with the monitorInterval configuration.
However according to the log4j 1.x docs here it does support log level changes runtime.
How can I change log behavior at runtime?
Log behavior can be set using configuration files which are parsed at
runtime. Using configuration files the programmer can define loggers
and set their levels.
The PropertyConfigurator defines a particular format of a
configuration file. See also the examples/Sort.java example and
associated configuration files.
Configuration files can be specified in XML. See log4j.dtd and
org.log4j.xml.DOMConfigurator for more details.
See the various Layout and Appender components for specific
configuration options.
In addition to configuration files, the user may disable all messages
belonging to a set of levels. See next item.

how to set log4j.configuration system variable in WebSphere 7?

I have a Java EE 5 web app I'm deploying to WebSphere 7 as an EAR file.
I want my log4j configuration to be external to the EAR file so I can tweak log content when needed without needing to rebuild and redeploy the EAR file.
My understanding is I can specify the location of my log4j.properties file by setting a
"system variable" called log4j.configuration. (ex. log4j.configuration=c:/log4j.properties)
My question is, how do I set this system variable in the WebSphere 7 admin console?
Browsing around I see there is Environment > WebSphere Variables, but that doesn't look right because that would be setting a variable for the entire server. I'm guessing I want to set a system variable just for my application EAR file.
Any help or suggestions is greatly appreciated!
Rob
The log4j.configuration property is a Java Virtual Machine system property. You can load this property by adding it to the end of your application server's list of generic JVM arguments. This is done in the WebSphere Console by navigating through the following:
Servers > Application servers > [app server name] > Process definition > Java Virtual Machine
Under Generic JVM arguments, add the following:
-Dlog4j.configuration=file:C:/log4j.properties
Click Apply at the bottom of this page, and save your changes. This will require a restart of the application server to take effect.
You can also use shared library for an application and put your log4j.xml there.
I find a solution to assign to each EAR or WAR an external log4j.xml configuration file:
I extracted the log4j.xml from our EAR, Zipped this lone XML into a JAR file. Placed it on the server in a path accessible by WebSphere,
Create a Shared Library (WebSphere > Environment > Shared Libraries) mapping the classpath to this archive. Make sure to select "Use an isolated class loader for this shared library" or you'd have to assign reference for each module of your application rather than just the parent EAR.
Assigning the reference within our EAR
(Application -> ApplicationType -> WebSphere enterprise applications -> EAR NAME -> Shared library references -> SELECT YOUR EAR -> Reference shared libraries -> SELECT THE LOG4J CONFIGURATION JAR) and ADD IT.
Restart the application
I used this way to assign a specific external log4j configuration file to each WAR in an an EAR.
Here you can find the original solution.
How to point Log4j.xml(not log4j2.xml) to external file
For Log4J (not Log4J2) in websphere 8.5 in Linux OS, please a custom properties under Servers > Application servers > [app server name] > Process definition > Java Virtual Machine.
property name: log4j.configuration property value : file:/xyz/abc/def/config/log4j.xml
NB: You don't need to append -D if you do it from custom properties. But if you give it under Generic JVM arguments use this:
-Dlog4j.configuration=file:/xyz/abc/def/config/log4j.xml -Dlog4j.debug
Each property must be separated by space. I added debug logs for Log4J itself to see from where it is picking the log4J.xml file.

Standard location for external web (Grails) application config files on linux

Is there a standard location on Linux (Ubuntu) to place external config files that a web application (Grails) uses?
UPDATE: Apparently, there is some confusion to my question. The way Grails handles config files is fine. I just want to know if there is a standard location on linux to place configuration files. Similar to how there is a standard for log files (/var/log). If it matters, I'm talking about a production system.
Linux configuration files typically reside in /etc. For example, apache configuration files live in /etc/httpd. Configuration file not associated with standard system packages often live in /usr/local/etc.
So I'd suggest /usr/local/etc/my-grails-app-name/. Beware that this means you can't run two different configurations of the same app on the same server.
I don't believe there is a standard location. You usually define the location for your external config files via the grails.config.locations property in config.groovy.
EDIT
After reading your comment, I suppose the standard locations would be:
Somewhere on the classpath
OR
In the .grails folder in your home directory.
As these are the defaults in config.groovy file.
grails.config.locations = [ "classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy"]
There's a plugin Standardized external configuration for your app which you might find useful if the grails.config.locations parameter is insufficient.

J2EE and Standard Java Application Log4j.properties

I have a project folder with merged J2ee application and standard java application. I am having trouble with configuring the Log4j.properties. I want to have separate log files 1 for my web application and another 1 for my standard application. I have two Log4j.properties files one under the root package of my web application and one under the root package of my standard application where both packages are under src folder.
When I ran both web app and standard app specifying only the file name, the log file for my webapp is created in the web server directory but my standard java app log file is created inside my WAR directory. I want the log file for my standard java app and my web app to be placed in the root folder that is why I specified in both log4j.properties absolute path to that folder. The problem is the only created log file depends on which log4j.properties file was detected and logs for both my web app and standard java app was written on that one file
This will be a detective work since I'll have more questions than you did.
I have a project folder with merged J2ee application and standard java application
This distinction seems to me a bit blurry. You have one project folder for two applications? It would be easier if they were separated. Is your standard java application a standalone application that can be run on a command line? A set of utility classes like a library?
I want to have separate log files 1 for my web application and another 1 for my standard application
I believe here lies your problem. If you're using your standard application's libraries in your web app, then during loading the application server will find two log4j.properties files on the classpath. You can not be sure 100% how this will behave.
When I ran both web app and standard app specifying only the file name, the log file for my webapp is created in the web server directory but my standard java app log file is created inside my WAR directory.
Running a web app specifying only the file name is unclear. What file name? When you say your WAR directory, do you mean the directory of your webapp, that's also inside your web server directory, or the directory under your (I'll assume you use Eclipse) IDE's project folder?
I want the log file for my standard java app and my web app to be placed in the root folder that is why I specified in both log4j.properties absolute path to that folder.
Root folder, like / in *nix? If you want them both to be placed in one folder, then you should remove one of log4j.properties files.
The problem is the only created log file depends on which log4j.properties file was detected and logs for both my web app and standard java app was written on that one file
Yes. You need to have only one log4j.properties file.

Log4J and Java Web Start, how to alternate between different configurations?

i'm starting with Log4J and i want to have a default log4j.properties in our Java Web Start distributed application, which only logs errors and important events.
But if something was wrong in one client i want to have a more detailed log, the way to do this is to define an alternate log4j configuration file in this client. This can be done by specifiying the alternate config file with the log4j.configuration system property.
but... How can i define an system property for this particular client in a java web start launched application? (i know that i can define theese propeties in the .jnlp file, but this affects all clients).
Our users work in windows environment but they often have a restricted permissions computer and they can't acces My Pc->Properties-->Advanced Options-->Enviroment Variables (i'm in a spanish configured computer i don't know the exact names in english).
Can you access to a defined directory on the client disk ?
If you can, you can define a convention : if no configuration file is found in the directory, the default config is used. Else, the specific configuration file is loaded.
You can do that with the PropertyConfigurator class of Log4J :
File log4jConfigFile == new File(conventionLocation);
if(log4jConfigFile.isFile() && log4jConfigFile.exists()) {
PropertyConfigurator.configure(conventionLocation);
} else {
PropertyConfigurator.configure(defaultEmbeddedJarLocation);
}
First off if you are using applets you should use an appender that can write to a remote location so you can actually see the errors without being physically on the local machine that the applet is running. Appender Types. Next, you need to create an appender with a threshold of whatever level you are logging the normal "access" type messages. Set the layout to whatever you desire. Then create another appender with a level of at least the level you log "errors" at as well as its own format that suits your needs as being "more detailed". That way when your code calls an error message it will use that different layout. Log4j is fairly complex but not impossible to understand. Look at the documentation at The log4j site and get your feet wet on some simple logging. After that you should be able to modify the code to get what you desire.

Resources