How to use log4j in any Java Project, Log4j Tutorial
Log4j is Apache's famous logging API and its been around from about quite a long time.
I will explain what I know from my understanding of log4j, because its more than 2 years, I have been using log4j for any of my development. Over the internet there are many articles and books available about this, and this is my honest try to simplify how to use log4j.
Basically log4j can be used any JAVA code (and of course in many other languages like C, C++, python, etc.)
How to use / log using log4j -
1) First of all, download log4j.x.x.x.jar file from - http://logging.apache.org/log4j/1.2/download.html OR older versions archive link is - http://archive.apache.org/dist/logging/log4j/ and extract to get jar file.
2) Include the downloaded jar in your class-path, (I have taken log4j-1.2.8.jar.)
3) Import org.apache.log4j.Logger in your code.
i.e. import org.apache.log4j.Logger;
4) Create one more file named log4j.properties, and include it in your projects classpath.
it would look like - (file name - log4j.properties)
e.g. Here is a simple POJO class, which uses log4j for logging
Here is screen-shoot of my simple sample project and what would be the logger output.
Now for more complex use,
1) With log4j we can separate out logs of different classes/code sections to different logging destinations
which we will configure in log4j configuration file.
2) There are two ways to custom-configure log4j - using external configuration file
a) Keep name of your log4j configuration file - same as -
1) log4j.xml OR
2) log4j.properties (depending upon whichever filetype you are using)
b) If you don't want to rename your configuration file, then
i) Load/configure log4j using your file,
For xml file type (e.g. abc.xml), use DOMConfigurator,
For Properties file type (e.g. abc.properties), use PropertyConfigurator.
3) Make sure you configure log4j with your custom properties before you use any logger code i.e. before you log anything.
e.g. Best position would be
a) Default/parameterized Constructor of any POJO, which loads first in your application (considering constructor runs first)
b) In case of Servlets, in init() method of servlet, (put this log4j initialization/configuration code in first servlet i.e. the servlet which runs first e.g. Login servlet,
NOTE - Don't put this initialization/configuration code in all/multiple servlets/POJOs, because it is unnecessary,(until and unless it is deliberately required), because once log4j is configured, it will work fine for all logger calls in that project.
If there are multiple java/ejb/web projects and cross-linking calls are made then,
YOU MUST CONFIGURE LOG4J FOR EACH PROJECT at least once before you use any logger statement in that project.
So, How to configure log4j using external configuration file? -
Here is how my project structure looks for my next code-snippets.
Note - You don't you to include these many log4j configuration files, any one would work, I just wanted to show different ways to load log4j external configuration file, so there are 5 different configuration files I have written.
So the source code for HowToUseLog4j.java -
Look at source code for HowToUseLog4j2.java -
Sample log4j configuration files from my project -
HowToLog4j.properties -
HowToLog4j.xml -
For more detailed reference visit -
http://logging.apache.org/log4j/1.2/manual.html
http://wiki.apache.org/logging-log4j/Log4jXmlFormat
http://en.wikipedia.org/wiki/Log4j
https://supportweb.cs.bham.ac.uk/documentation/tutorials/docsystem/build/tutorials/log4j/log4j.html
http://docs.jboss.org/jbossas/logging/JBossLog4j.pdf
For more reading, there is good book available
"The Complete log4j Manual" by Ceki Gülcü".
@) Printing JBoss (App Server) logs to Eclipse Console -
In your log4j.properties,
Still with above changes you won't be able to get logs in Eclipse Console because, Above config directs logs to JBoss's default console which is its default server logs.
Which is located inside JBOSS_HOME/server/..{minimal | all | default, etc}../deploy/log/server.log.
In order to get them to Eclipse Console, we have to pass one parameter to JBoss JVM, which can be done through many ways, like
1) by making changes run.bat or run.sh(for linux), or
2) while running JBoss through command prompt/terminal (in linux),
3) easiest way, through Eclipse, go to JBoss Server properties,
Put this one more argument in VM arguments of JBoss Launch Configuration parameters.
"-Dorg.jboss.logging.Log4jService.catchSystemOut=false" (without quotes) ,
Here are my screen-shots -
And
Enjoy.. :-)
I will explain what I know from my understanding of log4j, because its more than 2 years, I have been using log4j for any of my development. Over the internet there are many articles and books available about this, and this is my honest try to simplify how to use log4j.
Basically log4j can be used any JAVA code (and of course in many other languages like C, C++, python, etc.)
How to use / log using log4j -
1) First of all, download log4j.x.x.x.jar file from - http://logging.apache.org/log4j/1.2/download.html OR older versions archive link is - http://archive.apache.org/dist/logging/log4j/ and extract to get jar file.
2) Include the downloaded jar in your class-path, (I have taken log4j-1.2.8.jar.)
3) Import org.apache.log4j.Logger in your code.
i.e. import org.apache.log4j.Logger;
4) Create one more file named log4j.properties, and include it in your projects classpath.
it would look like - (file name - log4j.properties)
log4j.rootLogger=debug, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p]-%d{mm:ss}-(%F:%M:%L)-%m%n
e.g. Here is a simple POJO class, which uses log4j for logging
package temp1;
import org.apache.log4j.Logger;
public class MyClass {
public MyClass() {
}
public static void main(String[] args) {
//Get Root Logger
Logger rootLogger = Logger.getRootLogger();
rootLogger.debug("Here is some DEBUG");
rootLogger.info("Here is some INFO");
rootLogger.warn("Here is some WARN");
}
}
Here is screen-shoot of my simple sample project and what would be the logger output.
Now for more complex use,
1) With log4j we can separate out logs of different classes/code sections to different logging destinations
which we will configure in log4j configuration file.
2) There are two ways to custom-configure log4j - using external configuration file
a) Keep name of your log4j configuration file - same as -
1) log4j.xml OR
2) log4j.properties (depending upon whichever filetype you are using)
b) If you don't want to rename your configuration file, then
i) Load/configure log4j using your file,
For xml file type (e.g. abc.xml), use DOMConfigurator,
For Properties file type (e.g. abc.properties), use PropertyConfigurator.
3) Make sure you configure log4j with your custom properties before you use any logger code i.e. before you log anything.
e.g. Best position would be
a) Default/parameterized Constructor of any POJO, which loads first in your application (considering constructor runs first)
b) In case of Servlets, in init() method of servlet, (put this log4j initialization/configuration code in first servlet i.e. the servlet which runs first e.g. Login servlet,
NOTE - Don't put this initialization/configuration code in all/multiple servlets/POJOs, because it is unnecessary,(until and unless it is deliberately required), because once log4j is configured, it will work fine for all logger calls in that project.
If there are multiple java/ejb/web projects and cross-linking calls are made then,
YOU MUST CONFIGURE LOG4J FOR EACH PROJECT at least once before you use any logger statement in that project.
So, How to configure log4j using external configuration file? -
Here is how my project structure looks for my next code-snippets.
Note - You don't you to include these many log4j configuration files, any one would work, I just wanted to show different ways to load log4j external configuration file, so there are 5 different configuration files I have written.
So the source code for HowToUseLog4j.java -
package logicPro.log4j;
import java.io.InputStream;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* @author Pramod Khare
* Purpose - How to use log4j for logging in any java/web/ejb project
* (basically in any java class,JSP, Servlet) project.
*
* 1) First include log4j.X.X.X.jar (Relevant version) e.g. log4j-1.2.8.jar
* 2) There are two ways to custom-configure log4j - using external configuration file
* a) Keep name of your log4j configuration file -
* - same as -
* 1) log4j.xml OR
* 2) log4j.properties
* depending upon whichever fileType you are using
* b) If you don't want to rename your configuration file, then
* i) Load/configure log4j using your file,
* For xml file type, use DOMConfigurator,
* For Properties file type, use PropertyConfigurator.
* 3) Make sure you configure log4j with your custom properties
* before you use any logger code i.e. before you log anything.
* e.g. Best position would be
* a) Default/parameterized Constructor of any POJO, which loads first in your application
* (considering constructor runs first)
* b) In case of Servlets, in init() method of servlet, (put this log4j initialization/configuration
* code in first servlet i.e. the servlet which runs first e.g. Login servlet,
*
* NOTE - Don't put this initialization/configuration code in all/multiple servlets/POJOs, because it
* is unnecessary,(until and unless it is deliberately required),
* because once log4j is configured, it will work fine for all logger calls in that project.
*
* If there are multiple java/ejb/web projects and cross-linking calls are made then,
* YOU MUST CONFIGURE LOG4J FOR EACH of this project at least once
* before you use any logger statement in that project.
*
* n) Reference - http://docs.jboss.org/jbossas/logging/JBossLog4j.pdf
*/
public class HowToUseLog4j {
//Logger will be initialized with its complete class path, here its - logicPro.log4j.HowToUseLog4j
static Logger logger = Logger.getLogger(HowToUseLog4j.class);
//OR you can work with just Root Logger
public static Logger rootLogger = Logger.getRootLogger();
//You can create logger instance with any given string
public static Logger logger1 = Logger.getLogger("Category1");
public static Logger logger2 = Logger.getLogger("Category2");
public static Logger logger3 = Logger.getLogger("Category3");
//External Log4j Configuration files
public static String loj4jFileName = "HowToLog4j.properties";
public static String loj4jXMLFileName = "HowToLog4j.xml";
public HowToUseLog4j() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
//You don't have to manually configure your external log4j configuration file, (like abc.properties, abc.xml)
//if you keep its name as log4j.xml OR log4j.properties
try{
// TODO Auto-generated method stub
InputStream inStream = new HowToUseLog4j().getClass().getClassLoader().getResourceAsStream(loj4jFileName);
Properties props = new Properties();
props.load(inStream);
PropertyConfigurator.configure(props);
}catch(Exception e){
e.printStackTrace();
}
logger.debug("Here is some DEBUG");
logger.info("Here is some INFO");
logger.warn("Here is some WARN");
logger.error("Here is some ERROR");
logger.fatal("Here is some FATAL");
logger1.debug("Here is some DEBUG");
logger1.info("Here is some INFO");
logger1.warn("Here is some WARN");
logger1.error("Here is some ERROR");
logger1.fatal("Here is some FATAL");
logger2.debug("Here is some DEBUG");
logger2.info("Here is some INFO");
logger2.warn("Here is some WARN");
logger2.error("Here is some ERROR");
logger2.fatal("Here is some FATAL");
}
}
Look at source code for HowToUseLog4j2.java -
package logicPro.log4j;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.xml.DOMConfigurator;
public class HowToUseLog4j2 {
public static Logger logger1 = Logger.getLogger("Category1");
public static Logger logger2 = Logger.getLogger("Category2");
public static Logger logger3 = Logger.getLogger("Category3");
public static Logger logClass = Logger.getLogger(HowToUseLog4j2.class);
public String loj4jFileName = "HowToLog4j.properties";
public String loj4jXMLFileName = "HowToUseLog4j.xml";
public HowToUseLog4j2() {
try{
//Loading Log4j Configuration Properties (using .properties file)
//InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(loj4jFileName);
//Properties props = new Properties();
//props.load(inStream);
//PropertyConfigurator.configure(props);
//OR
//URL log4jURL = Loader.getResource("HowToLog4j.properties");
//PropertyConfigurator.configure(log4jURL);
//OR
//Loading Log4j Configuration Properties (using .xml file)
URL log4jXMLURL = Loader.getResource(loj4jXMLFileName);
DOMConfigurator.configure(log4jXMLURL);
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String argsp[]) throws IOException {
//To configure Log4j with our custom/external configurator file
new HowToUseLog4j2();
logger1.debug("This is an debug message.");
logger2.info("This is an info message.");
}
}
Sample log4j configuration files from my project -
HowToLog4j.properties -
log4j.rootLogger=debug, stdout
log4j.logger.logicPro.log4j.HowToUseLog4j = ERROR, stdout
log4j.logger.logicPro.log4j.HowToUseLog4j2 = ERROR, A1
log4j.logger.Category1 = TRACE, A1
log4j.logger.Category2 = ERROR, A1
log4j.logger.Category3 = INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%c]-[%p]-LogicPro-%d{mm:ss}-(%F:%M:%L)-%m%n
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%c]-[%p]-LogicPro-%d{mm:ss}-(%F:%M:%L)-%m%n
HowToLog4j.xml -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--above used log4j.dtd is there in log4j-x.x.x.jar, so thats why already included into classpath OR
it can be downloaded from next given URL-->
<!--<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER"
"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="myAppender" class="org.apache.log4j.ConsoleAppender">
<!--<param name="Threshold" value="TRACE" />-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%c]-[%p]-LogicPro-%d{mm:ss}-(%F:%M:%L)-%m%n" />
</layout>
</appender>
<!--
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="INFO" />
<param name="File" value="sample.log"/>
<param name="MaxBackupIndex" value="1"/>
<param name="MaxFileSize" value="100KB"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%c]-[%p]-LogicPro-%d{mm:ss}-(%F:%M:%L)-%m%n" />
</layout>
</appender>
-->
<!-- Logger configuration for Category1 -->
<logger name="Category1" additivity="false" >
<level value="ERROR" />
<appender-ref ref="myAppender"/>
</logger>
<!-- Logger configuration for Category2 -->
<logger name="Category2" additivity="false" >
<level value="INFO" />
<appender-ref ref="myAppender"/>
</logger>
<!-- Logger configuration for Category3 -->
<logger name="Category3" additivity="false" >
<level value="INFO" />
<appender-ref ref="myAppender"/>
</logger>
<!-- Logger configuration for logicPro.log4j.HowToUseLog4j -->
<logger name="logicPro.log4j.HowToUseLog4j" additivity="false" >
<level value="INFO" />
<appender-ref ref="myAppender"/>
</logger>
<!-- Logger configuration for logicPro.log4j.LogClass -->
<logger name="logicPro.log4j.HowToUseLog4j2" additivity="false" >
<level value="INFO" />
<appender-ref ref="myAppender"/>
</logger>
<!-- Logger configuration for ROOT logger -->
<root>
<priority value ="ERROR" />
<appender-ref ref="myAppender"/>
</root>
</log4j:configuration>
For more detailed reference visit -
http://logging.apache.org/log4j/1.2/manual.html
http://wiki.apache.org/logging-log4j/Log4jXmlFormat
http://en.wikipedia.org/wiki/Log4j
https://supportweb.cs.bham.ac.uk/documentation/tutorials/docsystem/build/tutorials/log4j/log4j.html
http://docs.jboss.org/jbossas/logging/JBossLog4j.pdf
For more reading, there is good book available
"The Complete log4j Manual" by Ceki Gülcü".
@) Printing JBoss (App Server) logs to Eclipse Console -
In your log4j.properties,
#Root Logger / Category Settings
log4j.rootLogger=debug, myAppender1, stdout
#In above config, you can add/configure as many appender as you want.
#e.g. log4j.rootLogger=debug, myAppender1, myAppender2, stdout
#To output Logs to Default Console along with others, add ConsoleAppender to
#to above config
#Default Console Appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p]-%d{mm:ss}-(%F:%M:%L)-%m%n
#Your own Appender e.g. any FileAppender (if any)
log4j.appender.myAppender1=org.apache.log4j.RollingFileAppender
log4j.appender.myAppender1.File=/Editor.log
log4j.appender.myAppender1.Append=true
log4j.appender.myAppender1.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppender1.layout.ConversionPattern=%5p - [%d{dd MMM yyyy HH:mm:ss}] %m%n
log4j.appender.myAppender1.MaxFileSize=5MB
log4j.appender.myAppender1.MaxBackupIndex=5
Make sure you have added a ConsoleAppender to rootLogger or any Logger for which you want to view logs in Eclipse Console.Still with above changes you won't be able to get logs in Eclipse Console because, Above config directs logs to JBoss's default console which is its default server logs.
Which is located inside JBOSS_HOME/server/..{minimal | all | default, etc}../deploy/log/server.log.
In order to get them to Eclipse Console, we have to pass one parameter to JBoss JVM, which can be done through many ways, like
1) by making changes run.bat or run.sh(for linux), or
2) while running JBoss through command prompt/terminal (in linux),
3) easiest way, through Eclipse, go to JBoss Server properties,
Put this one more argument in VM arguments of JBoss Launch Configuration parameters.
"-Dorg.jboss.logging.Log4jService.catchSystemOut=false" (without quotes) ,
Here are my screen-shots -
And
Note - basically what this VM argument does is, In JBoss, Log4jService class initializes the Log4j logging framework, and which has this CATCH_SYSTEM_OUT static-final-public variable, whose value is used as a flag to enable/disable catching of System.out, so in that case all our Console logs won't be printed to JBoss server.log file as its not listening to System.out anymore with our VM argument.
Comments
Post a Comment