Hi,
Log4j or any logging framework is very useful entity of any enterprise application, So that we can have a separate Application level logging using our own version of log4j.jar or any other logger framework version.
In this demonstration we will see how to use the log4j logging inside our Web Application, with it’s own version of “log4j.xml” file. We will also talk about the following points:
In this example we will mainly focus on following points
Point-1). How to use the “log4j.xml” which is placed inside “${YOUR_WAR}/WEB-INF/classes” directory.
Point-2). How to avoid using the JBoss provided logging framework or How to exclude the “org.apache.log4j” module provided by JBoss with the help of “${YOUR_WAR}/META-INF/jboss-deployment-structure.xml” file.
Point-3). Where to place your own version of “log4j.jar” file inside your WAR file. “${YOUR_WAR}/WEB-INF/lib”
Point-4). The Source code of this Demo can be downloaded from the following link (Git Repository):
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/ApplicationLevelLog4jDemo
Another Demo (uploaded on 26 Nov 2012) at EAR level.
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/EAR_Level_Log4jDemo
Developing WAR with it’s own logging
Step-1). Here we are using JBoss AS7.1 Final release latest build “jboss-as-7.1.0.Final” which can be downloaded from the following link: http://www.jboss.org/jbossas/downloads
Step-2). Create a directory with the name “src” somewhere in your file system like “/home/userone/ApplicationLevelLog4jDemo/”. Inside the “src” directory we are going to place our all source code and xml files for development.
Step-3). Write a simple “index.jsp” file inside “/home/userone/ApplicationLevelLog4jDemo/src” as following:
<html> <head> <title>Application Level Log4j Demo In JBoss AS7</title> </head> <body> <form action="TestServlet" method="Get"> Choose Log Level : <select name="logLevel"> <option>TRACE</option> <option>DEBUG</option> <option>WARN</option> <option selected="true">INFO</option> </select> <BR> Enter Mesage to be logged: <input type="textarea" name="logMessage"/> <BR> <input type="submit" name="submit" value="log the message"/> </form> </body> </html>
Step-4). Now we will write a simple Servlet based on Servlet3.0 specification with name “TestServlet.java” inside “/home/userone/ApplicationLevelLog4jDemo/src” as following
package servlets; import java.io.IOException; import java.io.PrintWriter; //servlet-api import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //log4j import org.apache.log4j.Logger; @WebServlet(value="/TestServlet") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static Logger logger = null; public void init() throws ServletException { logger= Logger.getLogger(TestServlet.class); } public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { PrintWriter out=response.getWriter(); String logLevel=request.getParameter("logLevel"); String logMessage=request.getParameter("logMessage"); out.println("<html><head><title>Log4j Logging Demo</title></head><body>"); if(logLevel.equals("TRACE")) { out.println("["+logLevel+"] "+logMessage+" (logged inside log file)."); logger.trace(logMessage); } if(logLevel.equals("DEBUG")) { out.println("["+logLevel+"] "+logMessage+" (logged inside log file)."); logger.debug(logMessage); } if(logLevel.equals("INFO")) { out.println("["+logLevel+"] "+logMessage+" (logged inside log file)."); logger.info(logMessage); } if(logLevel.equals("WARN")) { out.println("["+logLevel+"] "+logMessage+" (logged inside log file)."); logger.warn(logMessage); } out.println("<BR><BR><a href="index.jsp"> Want a different logging level? </a></body></html>"); } catch (Exception e) { e.printStackTrace(); } } }
Step-5). The most important part, We will need to write the following kind of “log4j.xml” file inside “/home/userone/ApplicationLevelLog4jDemo/src” as following :
NOTE: We need to just make sure that once the application is build this file should be present inside the ${WAR_NAME}/WEB-INF/classes directory.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="AppLogAppender" class="org.apache.log4j.DailyRollingFileAppender"> <param name="DatePattern" value="'.'yyyy-MM-dd"/> <param name="File" value="${jboss.server.log.dir}/MyAppLogsFile.log" /> <param name="Append" value="false"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %p - %m%n"/> </layout> </appender> <!-- The "category" represents the package names of your Application APIs which we want to log --> <category name="servlets"> <priority value="TRACE"/> </category> <root> <priority value ="TRACE"/> <appender-ref ref="AppLogAppender"/> </root> </log4j:configuration>
Step-6). Download and place the desired version of log4j jar (like “log4j-1.2.16.jar”) inside the “/home/userone/ApplicationLevelLog4jDemo/src”. So that after building the application this jar will be available inside the “${WAR_NAME}/WEB-INF/lib” directory.
Step-7). Now the most important part, In order to avoid using JBoss provided logging APIs, we need to place the following kind of “jboss-deployment-structure.xml” file inside “/home/userone/ApplicationLevelLog4jDemo/src” so that we can exclude the jboss logging APIs for our application and our application can use it’s own version of logging APIs.
NOTE: after building the WAR file make sure that the “jboss-deployment-structure.xml” is present inside the “META-INF” directory of your WAR file. Example: ${WAR_NAME}/META-INF/jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <exclusions> <module name="org.apache.log4j" /> </exclusions> </deployment> </jboss-deployment-structure>
NOTE: If you are using JBossAS 7.1.2 then In order to avoid this ClassCastException you will need to include the following System property in your JBoss -Dorg.jboss.as.logging.per-deployment=false
If you are using JBoss AS7.1.2 and not using the above mentioned “jboss-deployment-structure” file then you will see the following kind of exception at the time of deployment of your WAR:
18:05:41,507 ERROR [stderr] (MSC service thread 1-3) log4j:ERROR Could not create an Appender. Reported error follows. 18:05:41,509 ERROR [stderr] (MSC service thread 1-3) java.lang.ClassCastException: org.apache.log4j.DailyRollingFileAppender cannot be cast to org.apache.log4j.Appender 18:05:41,509 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:248) 18:05:41,510 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176) 18:05:41,510 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191) 18:05:41,510 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:523) 18:05:41,510 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:492) 18:05:41,511 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:1001) 18:05:41,511 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:867) 18:05:41,511 ERROR [stderr] (MSC service thread 1-3) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:794) 18:05:41,512 ERROR [stderr] (MSC service thread 1-3) at org.jboss.as.logging.LoggingConfigurationProcessor.deploy(LoggingConfigurationProcessor.java:111) 18:05:41,512 ERROR [stderr] (MSC service thread 1-3) at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:116) 18:05:41,513 ERROR [stderr] (MSC service thread 1-3) at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) 18:05:41,513 ERROR [stderr] (MSC service thread 1-3) at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) 18:05:41,513 ERROR [stderr] (MSC service thread 1-3) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 18:05:41,514 ERROR [stderr] (MSC service thread 1-3) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 18:05:41,514 ERROR [stderr] (MSC service thread 1-3) at java.lang.Thread.run(Thread.java:722)
Step-8). Now in order to build and deploy the above application we will write a very simple ant build script “build.xml” inside “/home/userone/jboss-as-7.1.0.Final/standalone/TESTING/ApplicationLevelLog4jDemo” as following:
<project name="Log4j_Basic_Demo" default="deploy"> <property name="jboss.home" value="/home/userone/jboss-as-7.1.0.Final" /> <property name="jboss.module.dir" value="${jboss.home}/modules" /> <property name="basedir" value="." /> <property name="tmp.dir" value="tmp" /> <property name="output.dir" value="build" /> <property name="src.dir" value="src" /> <property name="war.name" value="Log4jDemo.war" /> <path id="jboss.classpath"> <fileset dir="${jboss.module.dir}"> <include name="**/*.jar"/> </fileset> </path> <target name="init"> <delete dir="${output.dir}" /> <mkdir dir="${output.dir}" /> <delete dir="${tmp.dir}" /> <mkdir dir="${tmp.dir}" /> <mkdir dir="${tmp.dir}/WEB-INF/lib"/> <mkdir dir="${tmp.dir}/WEB-INF/classes"/> <mkdir dir="${tmp.dir}/WEB-INF/META-INF"/> <mkdir dir="${tmp.dir}/META-INF"/> </target> <target name="build" depends="init"> <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes" includes="*.java" classpathref="jboss.classpath" /> <copy todir="${tmp.dir}/WEB-INF/classes"> <fileset dir="${src.dir}" includes="**/*.java"/> </copy> <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/> <!-- Make sure to place the "log4j.xml" file inside ${WAR_NAME}/WEB-INF/classes directory--> <copy file="${src.dir}/log4j.xml" todir="${tmp.dir}/WEB-INF/classes"/> <!-- Make sure to place the "log4j-1.2.16.jar" file inside ${WAR_NAME}/WEB-INF/lib directory--> <copy file="${src.dir}/log4j-1.2.16.jar" todir="${tmp.dir}/WEB-INF/lib"/> <!-- Using this file we are going to satisfy the log4j dependency without directly placing the log4j.jar inside "WEB-INF/lib"--> <copy file="${src.dir}/jboss-deployment-structure.xml" todir="${tmp.dir}/META-INF"/> <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true"/> <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/> <delete includeEmptyDirs="true"> <fileset dir="${tmp.dir}"/> </delete> </target> <target name="deploy" depends="build"> <echo message="******************* Deploying the WAR file ${war.name} *********************" /> <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" /> <copy todir="${jboss.home}/standalone/deployments/"> <fileset dir="${output.dir}/"> <include name="${war.name}"/> </fileset> </copy> <echo message="******************* Deployed Successfully *********************" /> </target> </project>
NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script to point to your own JBoss AS7 directory.
Step-9). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:
For Unix Based OS: export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH For Windows Based OS: set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%
Step-10). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/userone/jboss-as-7.1.0.Final/standalone/TESTING/ApplicationLevelLog4jDemo” and then run the ant to build & deploy the webapplication. by running the command “ant deploy”
[userone@localhost ApplicationLevelLog4jDemo]$ ant Buildfile: build.xml init: [delete] Deleting directory /home/userone/ApplicationLevelLog4jDemo/build [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/build [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/lib [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/META-INF [mkdir] Created dir: /home/userone/ApplicationLevelLog4jDemo/tmp/META-INF build: [javac] Compiling 1 source file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/classes [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/WEB-INF/lib [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/tmp/META-INF [jar] Building jar: /home/userone/ApplicationLevelLog4jDemo/tmp/Log4jDemo.war [copy] Copying 1 file to /home/userone/ApplicationLevelLog4jDemo/build deploy: [echo] ******************* Deploying the WAR file Log4jDemo.war ********************* [echo] ********** build/Log4jDemo.war to /home/userone/jboss-as-7.1.0.Final//standalone/deployments ********** [copy] Copying 1 file to /home/userone/jboss-as-7.1.0.Final/standalone/deployments [echo] ******************* Deployed Successfully ********************* BUILD SUCCESSFUL Total time: 2 seconds
Step-11). Now you will able to access your application. “http://localhost:8080/Log4jDemo/index.jsp” try to access the servlet and then check the “${jboss.server.log.dir}/MyAppLogsFile.log” file to see if the application level logging is happening properly.
.
.
Thanks
Middleware Magic Team
September 7th, 2012 on 3:11 pm
Hello, where can I download the file .war?
Thank you
September 10th, 2012 on 12:12 am
Hi JacquesDeMolay,
In the following link “https://github.com/jaysensharma/MiddlewareMagicDemos/blob/master/ApplicationLevelLog4jDemo/build/Log4jDemo.war” click on the “RAW” button to download the war.
Thanks
Jay SenSharma
January 28th, 2013 on 8:33 pm
I just tried this and the build.xml file needed some editing to get working as the copy of the jboss-deployment-structure.xml file was
(1) commented out
(2) directed to the wrong directory, WEB-INF rather than META-INF.
A gentle pons asinorum, though ;-).
January 28th, 2013 on 8:35 pm
Oh, and I forgot to say thanks for this page, errors or not. Descriptions of how to use log4j in JBoss 7 are pretty hard to find.
February 7th, 2013 on 9:41 pm
Thanks Jay.
I’m using JBoss 7.1.0 Final. This doesn’t work for me.
The only logging I’m able to do is logging defined in the standalone.xml.
March 18th, 2013 on 10:51 am
Hello Experts,
Need help on jboss logging. i have an application deployed on jboss-4.2.3. Its log file is growing very fast. Logs are something similer to this “INFO [STDOUT] 274651420 [Thread-5] DEBUG com.arjuna.ats.arjuna.logging.arjLogger – Periodic recovery – second pass”
I want these DEBUG logs not to get into the server.log.
Can you please suggest a way how to get rid of these logs or log them into a diffrent log file like debuglogs.log
I am new to JBOSS and need this to fix, please help to resolve this.
thanks
January 10th, 2014 on 4:23 am
I tried on jboss 7.1.1. it did not worked.
i tried from the ear sample file.
deployed log files in jar, changed jboss-deployment-structure.xml
with exclusion.
No luck..:(