separate log4j2 files for web applications in single weblogic container - java

We have following Set up:
Application Server : Weblogic 10.3.6
We have 2 Managed Servers and we have 3 web applications wars deployed on both the managed servers.
All log4j2 jars are kept in server lib and loaded on server start up.
Now we want each web application to have its own logj2 configuration as we want to have control on logs levels.
we made separate log4j2 configuration file for each web application using tried initialising same using log4j2-web.jar in web.xml but we observed that when we load first web application, the log4j2 configuration file get loaded but when we try to load 2nd and 3rd web application,with their separate log4j config xmls,it doesnt load the new config file but sets log4j2 configurations of first web applications which got deployed first.
I tried to debug same and got to the point that as log4j2 jars are present in server class loader so they are common to all web application and log4j2 uses class loader to load logger context.
Now i want each application to have its separate log4j2 implementation which will not be common to other web application.so logging will be different for each application.
Kindly note, i cannot copy log4j2 libraries in WEB-INF/lib of each web applications as we already have size constrain for war.
Kindly suggest how can i implement separate log4j2 configuration for each web application in single weblogic container.
I tried to use JNDIContextSelector but its not working in Weblogic or i dont know how to make it work in weblogic as after doing all the required changes mentioned in log4j2 website,it was not able to find loggers.
Kindly help as i m stuck in same issue from last week.

Unfortunately by far the easiest solution that I am aware of is to include the log4j2 libraries in WEB-INF/lib of each web application...
If the log4j2 jar files are in the shared library directory, they are loaded by the shared classloader, and the configuration is shared between all web applications. This is how web containers and log4j2 are designed...
I would focus on this size constraint you mention. Why is there a size constraint on your war file? Perhaps there is another way to get around this size constraint? Would buying extra hard disk or a bigger server solve the issue? (Hardware is much much cheaper than the time you and perhaps your dev team are spending on this...)
If you are really desperate you can try to have one configuration with differently named loggers that log to different files or filter on different levels. When your application calls LogManager.getLogger, the string you pass becomes the name of the logger. This string can be used in the configuration to control filtering and the target appender. One thing you can do in your application, is giving loggers application-unique names like this:
// App.getPrefix() returns "app1." or "app2." etc: a unique name for each web app
Logger logger = LogManager.getLogger(App.getPrefix() + getClass().getName());
Then have different loggers and appenders in your configuration:
<Configuration status="debug">
<Appenders>
<File name="app1File" ...
<File name="app2File" ...
</Appenders>
<Loggers>
<Logger name="app1" level="TRACE">
<AppenderRef ref="app1File"/>
</Logger>
<Logger name="app2" level="TRACE">
<AppenderRef ref="app2File"/>
</Logger>
</Loggers>
</Configuration>
This is obviously a bit of a hack, and won't work for the classes outside your dev team's control...
You can also ask on the log4j-user mailing list to see if any of the other log4j2 team members have any ideas.

I have the same problem but using Tomcat9. I resolved this by explicitly providing a configuration location to each application when it is initializing logger context through a listener.
URL configLocation = Class.forName("com.example.MyAppListener").getResource("/log4j2.xml");
LoggerContext context = (LoggerContext) LogManager.getContext(false);
context.setConfigLocation(configLocation.toURI());
if(!context.isInitialized()) {
context.initialize();
}else {
context.reconfigure();
}

Related

Logging.properties in WAR file ignored by Liberty server

I have a Maven java project, my logging.properties is placed under resources folder. I have configured to print FINE level messages using console logger.
The WAR file generated has the properties file under WEB-INF/classes but, the application when deployed and executed, I can see only INFO level logs.
Should i initialize any LogConfiguration apart from having my logging.properties in the correct path ?
As describe here, you configure loggers in Liberty by something like this in the server.xml:
<logging traceSpecification="*=audit:com.myco.mypackage.*=debug"/>
and see the logging metatype doc to configure other aspects like log file size, number of logs to keep, etc.
Or, as the article mentions, you can use the bootstrap.properties
entries to do the same, e.g. com.ibm.ws.logging.trace.specification.
Though WebSphere also supports java.util.logging APIs, its full infrastructure isn't necessarily configured the same way as say Tomcat, which your app may be patterned after.
If you want to configure different logging behavior for different applications you can have the application Java code use a different Logger name for each, and then configure them differently through the single server.xml config (or also potentially separate the apps out onto different servers).
Dynamically changing the trace settings on a running server can be done simply by editing the server.xml config (as can dynamically configuring almost any aspect of Liberty).

How to disable request-level logging with the AWS Java SDK?

I'm trying to disable request level logging by the AWS Java SDK with Tomcat 8 on Linux. It's a fresh installation of tomcat 8 and my test servlet (which works) just prints to standard out, which by default goes to /var/log/tomcat8/catalina.out.
I'd like to disable the request level logging like - Sending Request... by the AWS SDK, so I've tried adding the following to my logging config at /usr/share/tomcat8/conf/logging.properties:
log4j.logger.com.amazonaws = WARN
log4j.logger.org.apache.http.wire = WARN
log4j.logger.com.amazonaws.request = WARN
...like the docs say here, but it's still doing the verbose logging. My tomcat startup information shows that the logging.properties file is being used:
org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/share/tomcat8/conf/logging.properties
Is there anything else I need to do to?
If you are using Logback, instead of Log4J or Java14 logging, put the following in logback.xml:
<configuration>
...
<logger name="org.apache.http.wire" level="WARN"/>
<logger name="com.amazonaws" level="WARN"/>
...
To specify an external logback.xml and using Spring Boot
-Dlogging.config="C:\logback\logback.xml"
or if you are not
-Dlogback.configurationFile=file:///C:/logback/logback.xml
Logback configuration via jvm argument
I had the same issue, none of the above helped actually.
Creating a logback.xml and putting it on classpath with below config fixed it:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<logger name="org.apache" level="ERROR" />
<logger name="httpclient" level="ERROR" />
</configuration>
Hope it helps the others.
"logging.properties" is the configuration file for Java Util Logging (JUL), witch is a different framework then Log4J. You can try to create a Log4J config file "log4j.properties" in the root of your classpath and insert the code from above: "log4j.logger.com.amazonaws = WARN" .
By Mark
Perhaps I should have been clearer: log4j is not required to control logging in the SDK. The SDK uses Apache Commons Logging, which is, as I already mentioned, an industry standard. Commons Logging is just a dispatch layer to an underlying logging implementation, so that customers can plug in any compliant logging framework and have it work. I used log4j in my examples because it's the one most commonly used, and therefore the most likely to be helpful in this public forum.
If your logging system works with Commons Logging, then you already know how to configure it. If it doesn't, then feel free to turn off Commons Logging altogether by passing the appropriate command-line argument to your JVM, as in my above response. If for some reason you can't change the java command line for your application, then you can use the following snippet in a Main class, to the same effect:
static {
System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog");
}
Again, to be absolutely clear: the SDK doesn't need log4j. Unfortunately, because all the underlying log implementations are configured differently, this means that we can't tell you exactly how to configure the logging unless we know which implementation your application uses. For that reason, we often use log4j syntax in our examples.
For more information about how Apache Commons Logging works and how to configure it, please read:
http://commons.apache.org/logging/guide.html

How to configure logging separately for Tomcat, an application, and a library with logback?

I'm trying to essentially configure logging in three places, independently. Ideally, each component that is logging is fully unaware of the others. I'd like to use logback for this, as it seems to have some decent features and performance.
Here are the places from which I would like to log from and to:
Tomcat (7) should log to ${catalina_home}/logs/catalina.out, and should only log Tomcat events (deployments, server startup, etc)
A web application hosted in Tomcat should log to ${catalina_home}/logs/application.log, and should only log application things, like results of request validations or errors
A library that is included in the web application should log to ${catalina_home}/logs/library.log, and should only log things specific to that library, like time it takes to interact with some other web-service or library-specific errors
I know this is probably not the way it would work, but I would think I need to have a logback.xml file for each concern. Actually, I have created them and added to the classpath such that I get a "logback.xml occurs multiple times on the classpath" error.
I can see why I would need to consolidat my application and my library logback configuration to a single logback.xml file, but how would I keep the container logging config separate from the application+library logging config? Adding a logback config file to my application, as well as logback enabling Tomcat as described here, still yields a "multiple logback.xml" error. And, Chapter 9 of the logback user manual, which talks about separation of logging, doesn't really show how to separate the container and applications (just multiple applications), unless I am missing something there.

Grails log configuration is hijacking the external log configuration, how to stop it?

I have a web application consisting of severals modules. All the modules are packaged together in one single ear.
One of them is a brand new groovy app, while others are more old school. This new grails app is not under my responsibility.
Notice that grails is not using any log4j.[properties|xml] file, but it as its own DSL which interact directly with log4j at runtime. This configuration is located inside a config.groovy script, packaged with the application.
Log4j is configured using an external file and the -Dlog4j.configuration option for the JVM.
The problem is the grail configuration is containing a very liberal config:
- set the root level to info
- add a console appender
The result is that the external configuration is hijacked by grails:
now there are two console appender (logging twice the same info) and lots of useless info data are logged.
Is there another solution than a programmatic approach, to tell grails to stop being rude ?
You could just turn off the grails logging so it uses the external logger
http://blog.saddey.net/2010/02/07/grails-how-to-use-native-server-logging-configuration-eg-tomcat-glassfish-jboss/

LOG4J as singleton, closing appenders on server stop and start (Attempted to append to closed appender)

We have a j2ee web environment. The server is configured to share session and possibly classloaders across multiple webapps. Basically, one classloader could server multiple web apps.
This seems to cause issues with log4j. Different webapps could have different log4j configurations but the logging may stop in one file.
We get the following error:
log4j:ERROR Attempted to append to closed appender named [mylogger]
Server: websphere6+
Log4j: 1.4.2
Java: 1.5
Example log4j.properties (webapp1):
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/usr/local/file1.log
log4j.additivity.com.app=false
Example log4j.properties (webapp2):
log4j.appender.Z=org.apache.log4j.RollingFileAppender
log4j.appender.Z.File=/usr/local/file2.log
log4j.additivity.com.app=false
Right now, logging from webapp2 may appear in the webapp1 logs and vice verse. We don't want that.
Log4j is probably initializing only once and loading randomly one or the other log4j.properties.
In our case, we decided for each WebApp to have an separate classloader. This way, we can decide to change Log Level on other framework like Spring or iBatis, for each WebApp.
The best way to debug Classloader (very common with WebSphere) is to find out which Log4j jar you are using and which log4.properties is used.
URL url = Logger.class.getProtectionDomain().getCodeSource().getLocation();
System.out.println("Sourcing Log4j from " + url

Categories

Resources