Sunday, April 8, 2012

Jamon : a quick and easy way to monitor Java web applications' performances

In this post, I would like to introduce a very handy way to monitor a Java web application's performance, using Jamon (click on the link to get to the Jamon project homepage). 


There are numerous ways to monitor the performances from a Java web application, but how easy it is set up and what kind of information you need in return, will determine the solution you'll choose. This could go from printing out (or logging) execution time, which has been explicitly calculated (stop time - start time), on the standard exit, to AOP using Spring Aspect or AspectJ.


The most interesting feature Jamon provides, is a web application showing you the monitoring's result.

Tools

  • Apache Tomcat 6.0.32
  • Jamon 2.73

How to use it (basic usage)

  1. Download Jamon distribution file
  2. Copy the jamon-2.73.jar library into the classpath of the project for which you want to enable monitoring.

    Remark
    Actually, you would rather copy this library to the directory from you web server, that contains the libraries that are shared across all the deployed applications. In my case, as I deployed a sample application on a Tomcat server, I copied the jamon-2.73.jar library into the %TOMCAT_HOME%/lib directory. Also, if you intend to use the provided monitoring console, you should definitely shared the library across all the applications.
  3. Deploy the provided monitoring console by copying the jamon.war file from the Jamon distribution to the %TOMCAT_HOME%/webapps directory.
  4. Add monitoring instructions to the code section you want to watch. As an example, here's some code to illustrate a practical use of Jamon : 

package org.blog.khy;

import java.io.IOException;
import java.util.Random;

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

import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;

/**
 * Servlet implementation class JamonDemoServlet
 */
public class JamonDemoServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 private static final Random RANDOM = new Random();
 
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  doGet(req, resp);
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  String action = req.getParameter("action");

  if (action.equalsIgnoreCase("LOGIN")) {
   login(req, resp);
  } else if (action.equals("CHECKOUT")) {
   checkoutCart(req, resp);
  }
 }

 private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  Monitor mon = MonitorFactory.start("login");

  // simulating login process
  long randomProcessTime = (long) (RANDOM.nextDouble() * 1000.0);
  resp.getWriter().print("PROCESSED LOGIN REQUEST");
  
  try {
   Thread.sleep(randomProcessTime);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }

  mon.stop();
 }

 private void checkoutCart(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  Monitor mon = MonitorFactory.start("checkout");

  // simulating cart checkout process
  long randomProcessTime = (long) (RANDOM.nextDouble() * 3000.0);
  resp.getWriter().print("PROCESSED CHECKOUT REQUEST");
  
  try {
   Thread.sleep(randomProcessTime);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }

  mon.stop();
 }
}


As you can see,  it's very simple to use Jamon : first, you'll retrieve and start a Monitor object by executing MonitorFactory.start(String label). The "label" argument designates the name under which the code section to monitor will be identified within the monitoring console. 


At the end of the code section that you're monitoring, just call the stop( ) method on the Monitor object. 


And voilà...


I've deployed this sample servlet and had it process a few requests (some with the "action" parameter = LOGIN, some otheres with the value CHECKOUT. 


Monitoring console

Finally, open the Jamon monitoring console which is deployed at the following address : http://localhost:8080/jamon

Click on the "JAMon Admin Page" link and you'll be brought to the page from which you could access all the monitoring info : 




Among all the infos, you'll have the number of times your monitored code has been executed, the average execution time, the longest/shortest execution time, and so on.

Remarks

You might think that Jamon is only useful during development but from my personal experience, you could deploy it along with your application into production : 
  • its footprint is practically non significative
  • you can disable/enable monitoring in one click, from the administration console
  • you can filter the monitor that you want to display in the list
That was just a slight overview of Jamon's features, you should definitely take a look at its documentation, as it provides some other monitoring functionalities.

7 comments:

  1. hi!! Yiu, great article... It would be great if you could explain it more.Can i use JAMon for implementing the website hitcounter(counting the website hit) please reply..

    ReplyDelete
  2. Hi there, sorry for the belated answer. In my opinion, you don't need Jamon to implement a website hit counter: defining a servlet filter will do the trick. As a matter of fact, in the code samples section of Jamon doc, they're actually defining a class that implements the Filter interface (see http://jamonapi.sourceforge.net/MonitorFilter.html). The advantage of embedding Jamon in an HTTP servlet filter would be that you could enable/disable it at any time, without redeploying you app.

    On the other hand, you could also consider using web analytic tools such as Google analytics, W3Counter, and so on.

    ReplyDelete
  3. Hi,I am trying to develop a tool in java that hosts on tomcat and the pc's that are connected in lan are getting monitored and their usage is getting displayed on the server.

    ReplyDelete
  4. Hi could you please provide JAMon configuration instructions for JBOSS7? On the website I see the instructions for JBOSS 4 (http://jamonapi.sourceforge.net/http_monitoring.html), but now there is total change in its folder structure in JBOSS7.

    ReplyDelete
  5. Hi there, sorry for the belated answer.

    As I've never worked with JBoss AS 7 myself, I had to take a look at the documentation first:

    - first,you'll need to create a JBoss module to expose the jamon-xx.jar library to all the web applications that need it;
    - then, you'll have to package your own web application in a .war whose manifest.mf file contains a reference to your JBoss module. Ex: "DEPENDENCY: the-name-of-my-jamon-module";
    - add global visibility to your JBoss module by adding







    to your JBoss instance configuration file (ex: standalone)
    Up to this point, I was able to deploy my own web application that uses Jamon API.

    Unfortunately, I haven't been able to deploy the jamon.war application properly yet.
    As a matter of fact, I guess we'd neet to retrieve its sources, define the manifest.mf with the neccessary dependencies and repackage as .war and deploy it.

    Hope that might help you.

    ReplyDelete
  6. Thanks KH Yiu for the reply. You can see my trails with Jboss 7.1 at http://stackoverflow.com/questions/26296207/jboss-7-what-is-the-subsystem-xmlns-for-the-jar-in-jboss-as-7-1-0-final-modules/26298441?noredirect=1#comment41267093_26298441, but now I realized in 7.1 they are not supporting valves, so I shifted to jboss 8 (wildFly) in which they have changed modules directory structure. Please let me know if you have any pointers for me to work with jboss 8? One more thing in your above post, it seems few lines are missing after your comment, - add global visibility to your JBoss module by adding .., I see only blank lines below that

    ReplyDelete
    Replies
    1. Jboss 7 supports valve.

      Add the valve in your jboss-web.xml

      Delete