Sunday, April 18, 2010

Eclipse Logback Plugin with JBoss AS

Recently in one of the forum threads an user asked how to use Logback Eclipse Plugin along with slf4j logging framework in JBoss AS. Having been tired of all those logging frameworks out there, I wasn't really too interested in looking at the details. But during this weekend, I had this sudden urge of trying out some simple application on which I wouldn't have to spend too much time or energy. So I decided to see what it takes to get the Logback Eclipse Plugin running against JBoss AS. So here's what it takes (well, nothing much actually - around half an hour or less):

Pre-requisites:

- JBoss Application Server 5.1.0 : Since this is the latest stable version, I decided to use this for testing. I don't see any reason why it shouldn't work against other version of the AS (4.x or 6.x).

- Latest release of slf4j library (1.5.11 at the time of writing this article) : JBoss AS-5 (and even AS-6) already ships with the slf4j jar in its lib folder. But since this is just another third party library, each user app should be able to package their own version of the jar within the app (and apply the usual classloading isolation configurations to the app). You can download slf4j from here

- Logback library version 0.9.9 : The logback library can be downloaded from the download site here. The only important thing to remember is to download version 0.9.9 (and *not* the latest one), because the latest versions of that plugin does not work due to a bug. Version 0.9.9 can be found here

- Eclipse IDE : I am currently on 3.4.1 Eclipse. I don't think the version of Eclipse would matter for this application.

- Logback Eclipse Plugin : The details of this plugin can be found here. It includes information on how to configure the plugin for Eclipse and where to download it from. At the time of writing this article, I found the plugin download here


Sample application:

Now that we have the required libraries and the setup ready, the next step is to write a simple application which makes use of slf4j logging framework backed by logback, to log some messages. Since this article is mainly meant as a quick start of getting logback Eclipse plugin working against JBossAS, I decide to use a simple servlet which does nothing more than log some messages.

The servlet looks like this:
 
package org.myapp.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleServlet extends HttpServlet
{

private static Logger slf4jLogger = LoggerFactory.getLogger(SimpleServlet.class);

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
slf4jLogger.info("******************************************");
slf4jLogger.info("***Hello World from a simple servlet***");
slf4jLogger.info("***Let's try out some logging messages***");
slf4jLogger.info("******************************************");

slf4jLogger.debug("This is DEBUG message");
slf4jLogger.info("This one is INFO message");
slf4jLogger.warn("Let's also send out a WARN message");
slf4jLogger.error("Well, sometimes we run into ERROR messages too");
try
{
throw new Exception("Intentional exception for demo");
}
catch (Exception e)
{
slf4jLogger.error("Error with stacktrace", e);
}
slf4jLogger.info("******************************************");
slf4jLogger.info("***That's it, folks!!!***");
slf4jLogger.info("******************************************");

}

}

It uses slf4j LoggerFactory to create a Logger and then use that logger to write out some log messages at different log levels. That's it.

The web.xml, just maps this servlet to some URL:



<?xml version="1.0" encoding="UTF-8"?>

<web-app>
<display-name>Logback example for JBossAS</display-name>

<servlet>
<servlet-name>SimpleServlet</servlet-name>
<servlet-class>org.myapp.servlet.SimpleServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>SimpleServlet</servlet-name>
<url-pattern>invokeServlet</url-pattern>
</servlet-mapping>

</web-app>


Then there's jboss-web.xml for classloading configuration:


<jboss-web>

<class-loading>
<loader-repository>
org.myapp:classloader=logback-example
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>


And finally, the important one, the logback.xml file which is responsible for configuring the consolePlugin:



<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="true">

<consolePlugin />

</configuration>


Yes, that's all you need in the logback.xml to get it working. More details can be found in its documentation here. The above config file creates a SocketAppender which uses port 4321 (by default). The Logback Plugin in Eclipse (also by default) connects to this 4321 to receive the log messages (when they are logged).

Note: The debug="true" in that logback.xml is just to show some debug messages when logback is reading that config file. You can remove that attribute, if you don't need such messages.

So now that we have these files ready, we just need to create a deployable application to test it out. I decided to use a .war file in this demo. You can even use a .ear file. I won't get into the details of how to create the .war file. Use your favourite build tool or an IDE to generate the .war file. The final .war should look like this:


myapp.war
|
|--- WEB-INF
| |
| |--- web.xml
| |--- jboss-web.xml
| |
| |--- lib
| | |
| | |--- logback-classic-0.9.9.jar
| | |--- logback-core-0.9.9.jar
| | |--- slf4j-api-1.5.11.jar
| |
| |
| |--- classes
| | |
| | |--- logback.xml
| | |
| | |--- org
| | | |--- myapp
| | | | |--- servlet
| | | | | |--- SimpleServlet.class



Note that the logback.xml is placed in .war/WEB-INF/classes folder because logback looks for that file in the classpath. Also notice the contents of .war/WEB-INF/lib folder - those are the jars that you'll have to package in your application. logback-classic-0.9.9.jar and logback-core-0.9.9.jar can be found in the logback download (which you did in the pre-requisites section). slf4j-api-1.5.11.jar can be found in the slf4j download.

Place this .war file in JBOSS_HOME/server/< servername>/deploy folder and start the server. Also open Eclipse IDE (if it's not already open) and open the "Logback View". Since we haven't yet logged anything from our application, the view will be empty (see image below).



So now let's invoke our servlet which logs the messages. As shown in the web.xml, I have mapped the servlet to the "invokeServlet" URL. So from my web browser, I access http://localhost:8080/myapp/invokeServlet

That's it, the servlet starts logging the messages and in the "Logback View" of Eclipse you will see the logged messages (see image below).



You have now successfully configured Logback Eclipse Plugin to work against JBoss AS. Did not take long to get it working!

4 comments:

Kevin Pauli said...

Do you know if there's any way to make jboss send its own log messages to slf4j rather than log4j?

Jaikiran said...

Kevin,

I think it should be possible. You however might have to come up with a custom LoggerPlugin implementation which delegates to slf4j. See this for details http://community.jboss.org/wiki/LoggingPlug-inJDKjavautillogging

Rockie said...

whats is logback-example in jboss-web.xml?
because as tutorial i have done everything but log view doesnt show logs
so help me

Jaikiran said...

The "logback-example" is just a part of the unique ObjectName for the application specific classloader. You can name it anything, it doesn't have to the logback-example.