How to control the log console output in log4j - java

I am new to JavaEE SSH environment, and currently I use log4j as my application's log system. But the problem is that if I set the log output level at DEBUG there are too many console output in MyEclipse, switch the output level to WARN will reduce the amount of the messages but also lost some information I interested in. So my question is how to let the log4j ONLY output ALL the log message generated by the Java file I am editing and DO NOT output ANY messages generated by others.

Assuming you are configuring log4j with a log4j.properties file, you can set a specific class or package to a different level like this:
log4j.logger.com.foo.MyClass=DEBUG
See http://logging.apache.org/log4j/1.2/manual.html for more introductory log4j stuff.

http://logging.apache.org/log4j/1.2/manual.html
You can configure the log-level of every Logger you created via Logger.getLogger("org.springframework") . You must search the configuration file for log4j.
Example for XML (from http://en.wikipedia.org/wiki/Log4j):
...
<logger name="org.springframework">
<level value="info"/>
</logger>
<!--
everything of spring was set to "info" but for class
PropertyEditorRegistrySupport we want "debug" logging
-->
<logger name="org.springframework.beans.PropertyEditorRegistrySupport">
<level value="debug"/>
</logger>
Hope that helps.

if you are running in the unix/linux environment, you can tail and grep the log file what exactly you are looking for. this is more flexible than modifying log4j configuration and much more powerful

I had the same issue whereby my log4j debug logging was being overwhelmed by Spring debugging in my JUnit unit tests (in Eclipse). I got around this by adding the following to my log4j properties file.
log4j.logger.org.springframework=FATAL

Related

Log4j2 no appenders could be found

After migrating from log4j v1.2 to log4j2, I have encountered some issues I am not sure how to solve.
I believe I have managed to change my xml-configuration and the logger initialization in the class files I have, but the IDE tells me that No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies)
It shouldn't be necessary to add a logger to classes/ packages I haven't created right? Maybe I am just missing the big picture here, but I hope you can guide me.
Thanks in regards
You use <AppenderRef ref="File"/> but appender File is not defined.
If you want to log everything to console, just change File to Console.
If you want to log to file, define File appender.

Weblogic Log4j Loggging Server Logging Bridge throws ClassCastException when starting up

With Weblogic 11g I have done the following:
1 Created log4j.xml file where I created a new appender:
<appender name="WEBLOGIC" class="weblogic.logging.log4j.ServerLoggingAppender">
<param name="Threshold" value="ERROR"/>
</appender>
<root>
<priority value="WARN"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="WEBLOGIC"/>
</root>
2 Updated the ${DOMAIN_HOME}/bin/setDomainEnv.sh script with these changes:
LOG4J_CONFIG_FILE="${DOMAIN_HOME}/config/log4j.xml"
if [ "${LOG4J_CONFIG_FILE}" != "" ] ; then
JAVA_PROPERTIES="${JAVA_PROPERTIES} Dlog4j.configuration=file:${LOG4J_CONFIG_FILE}"
export JAVA_PROPERTIES
fi
JAVA_OPTIONS="${JAVA_OPTIONS} ${JAVA_PROPERTIES} -Dweblogic.log.Log4jLoggingEnabled=true -Dwlw.iterativeDev=${iterativeDevFlag} -Dwlw.testConsole=${testConsoleFlag} -Dwlw.logErrorsToConsole=${logErrorsToConsoleFlag}"
3 Copied the log4j jars to the domain/lib
cp ./wlserver_10.3/server/lib/wllog4j.jar user_projects/domains/my_domain/lib/
cp ./wlserver_10.3/server/lib/consoleapp/APP-INF/lib/log4j-1.2.8.jar user_projects/domains/my_domain/lib/
4 Starts the AdminServer, but I get this error:
java.lang.ClassCastException:
weblogic.logging.log4j.ServerLoggingAppender cannot be cast to
org.apache.log4j.Appender
Keep step 1 and remove changes done in other steps.
Now copy the log4j.xml to $DOMAIN_HOME/lib folder. This will keep your log4j.xml in the server's classpath and the server will use this log4j.xml as its log4j configuration. No additional changes are required.
In setDomainEnv.xml file, please add the set log4j.xml location as below:
set LOG4J_CONFIG_FILE=C:\bea\user_projects\domains\dev\lib\log4j.xml
if NOT "%LOG4J_CONFIG_FILE%"=="" (
set JAVA_PROPERTIES=%JAVA_PROPERTIES% -Dlog4j.configuration=file:%LOG4J_CONFIG_FILE%
)
What you have to see is if despite the warning that you get, if the ServerLogging is effectively not working on your appliction on your domain.
Probably not even there since you are only copying the log4j to the domain/lib folder but not the wllog4j.jar.
So your setup looks like is doomed not to work in any case.
To me, It looks to me that you are undergoing Class Loader Vodoo Messup.
(1) You set a global log4j properties file for the entire app server.
(2) it looks like weblogic console app is itself a ear and it bundles its own LOG4J implementation library, which you are copying into your domain.
When the console app runs, it must for sure make use of Log4j and the class loader loading the Log4j Appender definition is most likely a level lower than the class loader that knows about the ServerLoggin bridge adapter.
I am beting its for reason like this that weblogic is geting rid of LOG4j in future gnerations of the product.
They have too many class loader issues - JUL logging you have the APP class loader behind the core classes - such as Handlers/Adapters.
Anyway.
(3) When weblogic runs, namley when it bootstraps the console it probably runs some sort class loader that gives a level of isolation to the libs bundled in the applicaiton and it sees:
Oh! How nice, LOG4j is here, leets initialize it.
Second, LOG4j bootstraps and hits head on your log4j.properties where you put the server logging appender in there - cross cutingly for everybody (including the weblogic application console).
He goes hunting for this library and where does it find it?
One of them, the wllog4j.jar he finds somewhere in the weblogic generic container libraries. While the base core classes of Log4j he finds a level lower in the domain configuration or in the EAR configuraiton of the console applicaiton.
This is not good.
Try the following:
(a) go into the weblogic console app, go to the Meta Inf folder and re-write the weblogi-application.xml
It will have a prefer applicaiton packages that looks like this:
org.apache.log4j.*</package-name--> <---- here I've commented this line.
If you comment the above line, the application class loader will search for log4j libraries in the highest parent that knows about these classes.
So if you put at the same level where your ServerLogger is found you should be fine.
(b) Pug the log4j implementation library at the same level where the wllog4j.jar will be found.
Check if you still get the casting exceptions.
Be very careful when you make server wide cross cuting configurations.
Good luck.

Optional printing of stack trace in Java

I am creating a java application in which there is a possibility that exceptions might be thrown. I am handling these exceptions in a try-catch block and printing appropriate messages so that the business users don't have to see the ugly stack trace in case of a failure.
But now when I debug, I would like to invoke the JAR file in such a way that it will print the stack traces for me, so that I can know where exactly the problem lies.
Can someone enlighten me on how this can be achieved?
You could use slf4j as a facade in order to be able to change quickly implementations and logback as the implementation for your logging. The combination of slf4j and logback are currently a very efficient logging system. In case you would want to use another implementation such as log4j, JDK 1.4, or Jacarta Commons logging you could just change the jar of the implementation(binding) with the one you want. It follows a quick user manual of how to use slf4j with logback.
Setting Your Environment
First of all you should import the necessary jars that are required to use slf4j.
Go to slf4j download page and download slf4j-1.7.0.zip
Extract slf4j-1.7.0.zip
Go to logback download page and download logback-1.0.7.zip
Extract logback-1.0.7.zip
Eclipse Guide
Go to your project in eclipse and right click on it. Select Properties.
From the left panel select Java Build Path
Select Libraries tab
Click Add External Jars
Locate your extracted folders and add logback-core-1.0.7.jar, logback-classic-1.0.7.jar from the logback-1.0.7 folder and slf4j-api-1.7.0.jar from the slf4j-1.7.0 folder. Click ok to return to the project.
Netbeans Guide
Go to your project in Netbeans and right click on it. Select Properties.
From the left panel select Libraries
Select Compile tab
Click Add Jar/Folder
Locate your extracted folders and add logback-core-1.0.7.jar, logback-classic-1.0.7.jar from the logback-1.0.7 folder and slf4j-api-1.7.0.jar from the slf4j-1.7.0 folder. Click ok to return to the project.
*In case you are not using any of the above environments you should add the above 3 jars in your classpath manually. Dependening your operating system there is a different procedure to follow.
Using the logging framework
First of all you should import the required dependencies:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Each class that you would like to log should have a private logger:
private final Logger logger = (Logger) LoggerFactory.getLogger(this.getClass())
By having a seperate logger for each class you provide more flexibility and easier change of your logging levels(WARN,ERROR,INFO,DEBUG).
According to the log level that would like to use you should have
logger.info("Your info message");
logger.error("Your error message");
logger.debug("Your debug message");
logger.warn("Your warn message");
There is also the possibility to use more complex method calls dependening on your needs. For example if you want to debug and show also the stacktrace you should use
logger.debug("Your debug message",e);
(e stands for a catched exception).
For example:
try{
//some code
}catch (IOException e){
logger.debug("An IOException was thrown at this method ",e);
logger.error("An IOException was thrown at this method ",e);
}
*At this point without adding any other configuration you have a simple logging system. In case you want more advanced configuration
read the advanced settings of logback that i have posted below.
Advanced Settings of logback
In order to have a more advanced logging system you should create an additional file which will contain all the logging configuration. For this example i am going to use the logback.xml. For more info regarding the different files of logback please refer to logback configuration.
At this point you should create a folder named resources and add it in the buildpath of your project.
Eclipse Guide
Create a folder named resources(You must see the folder in your project)
Go to your project in eclipse and right click on it. Select Properties.
From the left panel select Java Build Path
Select Source tab
Click Add Folder
Tick the resources folder that you have created and click ok. Click ok to return to the project.
At this point you should see the resources folder as a package.
Netbeans Guide
Create a folder named resources(it will not be visible yet on the projects view..Only in the files view)
Go to your project in Netbeans and right click on it. Select Properties.
From the left panel select Sources
In the Source package folders click Add Folder.
Select the resources folder and click ok.
You should see the folder created as a package.
*The name of the folder could be any name that you like. For convenience i named it resources.
The following applies in both Eclipse and Netbeans.
*In case you will not have the following file in your classpath which specify specific settings in the logging framework, the root logger level is automatically assigned in DEBUG. That means that all the logging levels are going to be logged. Debug is the higher level.
Create a folder named logback.xml and place it inside the resources folder.
Inside logback.xml place the following tag.
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>[%-5level] - %msg%n
</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<append>false</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %class - %msg%n
</pattern>
</encoder>
<File>log/log.txt</File>
</appender>
<logger name="org.test" level="INFO" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.test" level="DEBUG" additivity="false">
<appender-ref ref="FILE" />
</logger>
<root level="OFF">
</root>
The above configuration contains 2 different appenders,one in the console and one in a file named log.txt. The file is going to be placed in a folder named log. In case the folder log does not exist is going to be created automatically.
The pattern that you are going to use depends on you and how informative your messages will be.
In the current configuration the console appender is less descriptive and shows only the logging level and the message, comparing to the file appender which contains logging level, thread name, class name, time and message. The value append is set to false in order to create a new log file after every run of your application.
The above configuration uses 2 different loggers for the same package. The first logger prints only the info messages in the console and the second logger prints the debug messages to a file. This is achieved by using the filter that is placed inside the appenders.
*In the logger name you can have the fully qualified name of your class or the package name. In this case i assumed package structure
org.test and placed the class inside this package. If you have the
fully qualified name of the class the logging configuration will be
applied only for this class. In case you use the package name, all the
classes inside this package are going to follow the above
configuration.
There are many different ways to use the appenders and loggers and it depends in your needs and the complexity of your program. According to the situation that you described i believe that above solution could meet your needs.
P.S. For more descriptive definitions and more advanced configurations you could refer to the Logback manual
Why not use Logging levels.?
DEBUG for your technical errors
and INFO or ERROR with the business codes that your users understand.
such things are usually handled with loggers and different log levels.
You typicaly have 3 log levels, general logs, warnings and errors.
When you output you decide which level a message is
when you start your application you say to your loggger which level it should display.
For your users this will be ERROR, only the worst things should be visible, for yourself you would output everything
create two classes with the same package/name at two different locations
public class PrintStackTraceUtil
{
public static void printStackTrace(Throwable err)
{
//ignore
}
}
and
public class PrintStackTraceUtil
{
public static void printStackTrace(Throwable err)
{
err.printStackTrace();
}
}
when compiling your java program, put only one of those paths in your sourcepath

two log4j files for EAR with two modules

I have an EAR that is made up of two modules. Both expose services and share common code.
Imagine that the ear has a common.jar shared by a webservices.war and webapp.war.
I use log4j to log the activities. I would like to be able to have two log files (webservices.log and webapp.log) capturing the events that are specific to each of them plus all the stuff that is handled by the common.jar.
How should I configure my categories and my appenders to achieve this?
At the moment I have the following packages:
com.myapp for shared stuff
com.myapp.webservices for the webservices and
com.myapp.webapp for the webapp.
My problem is that I don't know how I can capture the com.myapp (common stuff) in both log files by using a single log4j configuration file.
I have tried setting up multiple configuration files but when JBoss would work OK Websphere would break and the other way round...
Thank you
You can keep log4j configuration anywhere you like, just make sure Logger is able to initialize the engine from the configuration file. I don't see any reason why one configuration file is not working for both Jboss and WebSphere. Could you be more specific on what is breaking?
You need to configure two file appenders named webservices and webapp in same log4j configuration files and using the package names redirect to the relevant appender.
<logger name="com.myapp.webservices">
<appender-ref ref="webservices" />
</logger>
<logger name="com.myapp.webapp">
<appender-ref ref="webapp" />
</logger>

Enabling logging of a third party component

In one of codes I am using Jetty. I am using the Jetty jar and imports the Classes from my Java code.
Jetty's default log level is INFO if not configured specifically. We can enable DEBUG mode by code. The logger seems to be a log4j one.
org.mortbay.log.Logger jettyLogger = org.mortbay.log.Log.getLog();
jettyLogger.setDebugEnabled(true);
Assume I haven't added this to the code. And now I want to enable logging by some other method. Can I do this using a log4j configuration?
Here's the Jetty documentation page on how to use it's logger.
You should just be able to use a standard log4j.properties file if you're using log4j as your logging implementation
Add this to your log4j.xml file
<category name="org.mortbay">
<priority value="debug" />
</category>

Categories