Thursday, May 28, 2009

Measuring time to generate pages in a servlet

In a web application, we might want to measure the time taken to generate a page and display for instance on the footer something like "This page was generated in 6 seconds".

There are probably many ways to do it but one simple way is to use Filters which are used to process the HTTP input before the request is given to the controller and its output. So we just need to create a filter that will save the time when the request is received in an attribute that can later on be used in the jsp.

Let's create the Filter in the class com.example.RequestTimeFilter that will put the date when the request is received on the attribute "requestDate".


package com.example.RequestTimeFilter;

import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class RequestTimeFilter implements Filter
{
private FilterConfig filterConfig;

public void doFilter(ServletRequest req,
ServletResponse res, FilterChain fc)
throws java.io.IOException, javax.servlet.ServletException
{
req.setAttribute("requestDate", new Date());
fc.doFilter(req,res); // invoke next item in the chain --
// do nothing to the output
}

public FilterConfig getFilterConfig()
{
// Execute tasks
return filterConfig;
}

public void setFilterConfig(FilterConfig cfg)
{
// Execute tasks
filterConfig = cfg;
}

public void destroy() {
// TODO Auto-generated method stub

}

public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub

}


Now let's edit the file WEB-INF/web.xml by adding the following lines:

<filter>
<filter-name>Request Time Filter</filter-name>
<filter-class>com.example.RequestTimeFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>Request Time Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


Now in your jsps, you can do something like:

This page was generated in
<fmt:formatnumber type="number"
minfractiondigits="2"
maxfractiondigits="2"
value="${(now.time - requestDate.time) / 1000}"/>
seconds.

Enjoy!