Weblogic12 + Log4j logging not writing to server logs - java

I know there are lots of Q's regarding this, but I did go through all of them, and kinda confused myself more, I am listing the steps I followed, please let me know where I messed it up.
1) I just want to use Log4j on application level, so need to copy WL_HOME/server/lib/wllog4j.jar, and the log4j.jar in Domail_Home/Lib?
2) I am using Maven, I added the Log4j dependency in my pom.xml [war].I have my WAR wrapped in EAR.
3) Since I want to write the logs in weblogic managed server logs file, I created a custom appender, to use weblogic, NonCatalogAppender as mention in the link - https://blog.desgrange.net/2010/02/15/logging-in-weblogic-console-with-log4j.html
4) I copied the log file in my war/src/main/resources and i see maven added them to classpath i.e war/target/classes, see below for my lo4j xml
http://jakarta.apache.org/log4j/'>
<!-- stdout appender settings -->
<appender name="STDOUT" class="com.xyz.logging.util.WeblogicAppender">
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- notes on patterns:
%p - priority (i.e. level) of message
%c - class that threw error
%m - message in logger's method, e.g. "Exiting application HERE..."
%n - carriage return
%d - date information
-->
<param name="ConversionPattern" value="%c{1} %m"/>
</layout>
</appender>
<!-- settings for root debugger -->
<root>
<level value="DEBUG"/>
<appender-ref ref="STDOUT"/>
</root>
5) Now I didn't change anything on the config level, but I don't see anything appending to server logs. When I initialize NonCatlogLogger manually and call the logger it works fine:
NonCatalogLogger logger =new NonCatalogLogger("XYZ");
logger.debug("This is the debug message")
6) When I debug the application in eclipse, it looks like my custom appender is never called.

Got it, just need to put below into arguments under "server start".
-Dweblogic.log.Log4jLoggingEnabled=true

Related

System.out.println not printing to console

I have a Spring web app running on Wildfly 8.* and for some reason it won't print to the console. I see all the console logs and stack traces fine but the System messages just don't appear.
The problem might be with my log4j setup so I'll post that config;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC
"-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
I've ran apps on JBoss 7.1 before however without this problem so I'm really at a loss on what could be wrong.
Feel free to ask about any of my other config not sure what would be needed.
Edit:
logger.org.jboss.as.config.level=DEBUG
logger.org.jboss.as.config.useParentHandlers=true
logger.jacorb.config.level=ERROR
logger.jacorb.config.useParentHandlers=true
logger.org.apache.tomcat.util.modeler.level=WARN
logger.org.apache.tomcat.util.modeler.useParentHandlers=true
logger.com.arjuna.level=WARN
logger.com.arjuna.useParentHandlers=true
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
handler.CONSOLE.level=INFO
handler.CONSOLE.formatter=COLOR-PATTERN
handler.CONSOLE.properties=autoFlush,target,enabled
handler.CONSOLE.autoFlush=true
handler.CONSOLE.target=SYSTEM_OUT
handler.CONSOLE.enabled=true
handler.FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
handler.FILE.level=ALL
handler.FILE.formatter=PATTERN
handler.FILE.properties=append,autoFlush,enabled,suffix,fileName
handler.FILE.constructorProperties=fileName,append
handler.FILE.append=true
handler.FILE.autoFlush=true
handler.FILE.enabled=true
handler.FILE.suffix=.yyyy-MM-dd
handler.FILE.fileName=C\:\\wildfly-8.2.0.Final\\standalone\\log\\server.log
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.PATTERN.properties=pattern
formatter.PATTERN.pattern=%d{yyyy-MM-dd HH\:mm\:ss,SSS} %-5p [%c] (%t) %s%E%n
formatter.COLOR-PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.COLOR-PATTERN.properties=pattern
formatter.COLOR-PATTERN.pattern=%K{level}%d{HH\:mm\:ss,SSS} %-5p [%c] (%t) %s%E%n
Here is my logging config in my standalone deployments folder.
I had a log4j.properties file at the root level of the .war (WEB-INF/classes) from years ago that caused the same issue - deletion fixed it
Since you are using a logging framework, there are 2 ways to fix it:
Remove the logging framework and all the configuration files (why would I do that)
Move your log4j.properties file from src/main/resources to WEB-INF folder.
Quoting: JBoss Docs, Section 'Per Deployment Logging'
Per-deployment logging allows you to add a logging configuration file to your deployment and have the logging for that deployment configured according to the configuration file. In an EAR the configuration should be in the META-INF directory. In a WAR or JAR deployment the configuration file can be in either the META-INF or WEB-INF/classes directories.
The following configuration files are allowed:
logging.properties
jboss-logging.properties
log4j.properties
log4j.xml
jboss-log4j.xml
I usually have trouble configuring logs per deployment in wildfly, but you can use the logging system from wildfly, changing logging configuration of your standalone ou domain config files to this would do the trick:
<root-logger>
<level name="TRACE"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>

Confuguring log4j for multiple projects in the same app. server

We have a bunch of projects that get deployed in the same Jboss app. server. Each project has its own log4j.properties in its WEB-INF directory.
The idea is for each project to have its own logfile into which it writes its logs.
Any ideas on how this can be achieved.
First of all you don't mention the JBoss version you're using. You've to take in mind that JBoss versions prior to AS7 include its own log4j version (libraries and configuration file: conf/jboss-log4j.xml), so by default JBoss will ignore the log4j.properties file you've in each of your projects.
That said, you have two approaches to configure a log file for each application:
Centralized way: configure it in Jboss, through the
conf/jboss-log4j.xml. This way you won't need to modify your
applications, or
Modify your applications so that they take their own
log4j libraries (you'll have to include them in the ear/war), not
the Jboss ones.
For the first approach you'll have to define an appender for each of your applications, and then categories for the application packages, in the conf/jboss-log4j.xml file. For example, to configure a log file for an application called app1.war which classes are in a package called com.foo.app1, you'd have to add:
<appender name="APP1_APPENDER" class="org.jboss.logging.appender.DailyRollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/app1.log"/>
<param name="Append" value="true"/>
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] (Thread) Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
</layout>
</appender>
...
...
<category name="com.foo.app1" additivity="true">
<priority value="INFO"/>
<appender-ref ref="APP1_APPENDER"/>
</category>
You'll have to add a customized set of blocks like this one for each project you want to define a log file for, respectively.
If you prefer the second approach, as said you'll have to include the log4j libraries in each project and isolate each application so that it takes the libraries included in the application not the ones from JBoss. Look at section 10.3.7 of the Jboss logging file for more information about this approach.

What is the best way to use log4j in the web application?

We are starting a Spring MVC based web application. We will be using tomcat as the web server.
I need to configure log4j in the application and log to the application specific file and not to the tomcat log files.
e.g. tomcat has its own log files like localhost.log etc. I want something like myAppName.log in the tomcats log folder.
The logging configuration will go in lo4j.xml or log4j.properties in the application war file.
Plus I dont want to hard code the output log file in the web application.
But I am not sure how to do this.
Please help me. As well correct me if I am wrong somewhere.
Do like this, initialize the logger with following code,
Logger log = Logger.getLogger(this.getClass());
log the information like follows,
log.debug("My message");
and place the log4j.xml in your class path. content like follows,
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="infoLogsFile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="MyApplication.log"/>
<param name="Threshold" value="DEBUG"/>
<param name="MaxFileSize" value="100MB"/>
<param name="ImmediateFlush" value="TRUE"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
<root>
<priority value ="DEBUG" />
<appender-ref ref="infoLogsFile"/>
</root>
</log4j:configuration>
Do not forget to add the required jars like log4jXXX.jars and apache common logging jars. with this you will be able to see all log messages in MyApplication.log file creates in bin folder of your tomcat.
Try this:
Put the log4j jar as part of the web application
Do not put a configuration as part of your web application
Create your log4j.xml wherever you like
When you start tomcat provide this argument
-Dlog4j.configuration=file:///.../log4j.xml

java logging nightmare and log4j not behaving as expected with spring + tomcat6

I have a spring application that has configured log4j (via xml) and that runs on Tomcat6 that was working fine until we add a bunch of dependencies via Maven. At some point the whole application just started logging part of what it was supposed to be declared into the log4.xml
"a small rant here" Why logging has to be that hard in java world? why suddenly an application that was just fine start behaving so weird and why it's so freaking hard to debug?
I've been reading and trying to solve this issue for days but so far no luck, hopefully some expert here can give me some insights on this
I've added log4j debug option to check whether log4j is taking reading the config file and its values and this is what part of it shows
log4j: Level value for org.springframework.web is [debug].
log4j: org.springframework.web level set to DEBUG
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.compass] additivity to [true].
log4j: Level value for org.compass is [debug].
log4j: org.compass level set to DEBUG
As you can see debug is enabled for compass and spring.web but it only shows "INFO" level for both packages. My log4j config file has nothing out of extraordinary just a plain ConsoleAppender
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
What's the trick to make this work? What it's my misunderstanding here?
Can someone point me in the right direction and explain how can I make this logging mess more bullet proof?
It might not be log4j that is doing the logging, and hence your log4j config would be ignored. Spring logs using Commons Logging, which is an api that can delegate to various logging frameworks, including log4j. To decide which implementation to use, commons logging looks into the classpath.
If you have added a dependency that dragged its own logging implementation into the classpath, commons logging might now use the other implementation.
I recommend to set a breakpoint at a call to the logging facility, and trace the execution to see which logging implementation is used.
As it was working until you loaded a number of dependencies via Maven, perhaps there's a Log4j configuration loaded inadvertently via these dependencies ?
Run mvn dependency:tree to see what's being loaded, and then see if any of these dependencies has a Log4j configuration.
I think your problem is that you're not setting the threshold param on your appenders, and (maybe) because you're not assigning those appenders to your loggers.
Try adding param name="threshold" value="debug" to your appenders and then explicitly adding them to the specific (or root) loggers like so:
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="threshold" value="debug" />
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<logger name="org.springframework.web">
<level value="debug" />
<appender-ref ref="console" />
</logger>
Also, this page says "This appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower" which is probably the source of your problem.
This seems like a good thread for you to read:
http://forum.springsource.org/showthread.php?t=88250
Cutting to the chase, it seem that the poster had a problem with a Tomcat security setting. An updated Tomcat policy file fixed the issue.
Probably has something do with reading outside of the webapp for your log4j.xml file.

Creating multiple log files of different content with log4j

Is there a way to configure log4j so that it outputs different levels of logging to different appenders?
I'm trying to set up multiple log files. The main log file would catch all INFO and above messages for all classes. (In development, it would catch all DEBUG and above messages, and TRACE for specific classes.)
Then, I would like to have a separate log file. That log file would catch all DEBUG messages for a specific subset of classes, and ignore all messages for any other class.
Is there a way to get what I'm after?
This should get you started:
log4j.rootLogger=QuietAppender, LoudAppender, TRACE
# setup A1
log4j.appender.QuietAppender=org.apache.log4j.RollingFileAppender
log4j.appender.QuietAppender.Threshold=INFO
log4j.appender.QuietAppender.File=quiet.log
...
# setup A2
log4j.appender.LoudAppender=org.apache.log4j.RollingFileAppender
log4j.appender.LoudAppender.Threshold=DEBUG
log4j.appender.LoudAppender.File=loud.log
...
log4j.logger.com.yourpackage.yourclazz=TRACE
Perhaps something like this?
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- general application log -->
<appender name="MainLogFile" class="org.apache.log4j.FileAppender">
<param name="File" value="server.log" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
</layout>
</appender>
<!-- additional fooSystem logging -->
<appender name="FooLogFile" class="org.apache.log4j.FileAppender">
<param name="File" value="foo.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
</layout>
</appender>
<!-- foo logging -->
<logger name="com.example.foo">
<level value="DEBUG"/>
<appender-ref ref="FooLogFile"/>
</logger>
<!-- default logging -->
<root>
<level value="INFO"/>
<appender-ref ref="MainLogFile"/>
</root>
</log4j:configuration>
Thus, all info messages are written to server.log; by contrast, foo.log contains only com.example.foo messages, including debug-level messages.
I had this question, but with a twist - I was trying to log different content to different files. I had information for a LowLevel debug log, and a HighLevel user log. I wanted the LowLevel to go to only one file, and the HighLevel to go to both a file, and a syslogd.
My solution was to configure the 3 appenders, and then setup the logging like this:
log4j.threshold=ALL
log4j.rootLogger=,LowLogger
log4j.logger.HighLevel=ALL,Syslog,HighLogger
log4j.additivity.HighLevel=false
The part that was difficult for me to figure out was that the 'log4j.logger' could have multiple appenders listed. I was trying to do it one line at a time.
Hope this helps someone at some point!
For the main logfile/appender, set up a .Threshold = INFO to limit what is actually logged in the appender to INFO and above, regardless of whether or not the loggers have DEBUG, TRACE, etc, enabled.
As for catching DEBUG and nothing above that... you'd probably have to write a custom appender.
However I'd recommend not doing this, as it sounds like it would make troubleshooting and analysis pretty hard:
If your goal is to have a single file where you can look to troubleshoot something, then spanning your log data across different files will be annoying - unless you have a very regimented logging policy, you'll likely need content from both DEBUG and INFO to be able to trace execution of the problematic code effectively.
By still logging all of your debug messages, you are losing any performance gains you usually get in a production system by turning the logging (way) down.
Demo link: https://github.com/RazvanSebastian/spring_multiple_log_files_demo.git
My solution is based on XML configuration using spring-boot-starter-log4j. The example is a basic example using spring-boot-starter and the two Loggers writes into different log files.

Categories

Resources