views:

109

answers:

1

I'm looking to create a filter that can give me two things: number of request pr minute, and average responsetime pr minute. I already got the individual readings, I'm just not sure how to add them up.

My filter captures every request, and it records the time each request takes:

public void doFilter(ServletRequest request, ...()  
{       
    long start = System.currentTimeMillis(); 
    chain.doFilter(request, response);
    long stop = System.currentTimeMillis();

    String time = Util.getTimeDifferenceInSec(start, stop);
}

This information will be used to create some pretty Google Chart charts. I don't want to store the data in any database. Just a way to get current numbers out when requested

As this is a high volume application; low overhead is essential.

I'm assuming my applicationserver doesn't provide this information.

+1  A: 

I did something similar once. If I remember well, I had something like

public class StatisticsFilter implements ... 
{
    public static Statistics stats;

    public class PeriodicDumpStat extends Thread
    {
       ...
    }

    public void doFilter(ServletRequest request, ...()  
    {       
      long start = System.currentTimeMillis(); 
      chain.doFilter(request, response);
      long stop = System.currentTimeMillis();
      stats.add( stop - start ); 
    }

    public void init()
    {
       Thread t = new PeriodicDumpStat();
       t.setDaemon( true );
       t.start();
    }
}

(That's only a sketch)

Make sure that the Statistics object is correctly synchronize, as it will be accessed concurrently.

I had a background DumpStatistics thread that was periodically dumping the stats in an XML file, to be processed later. For better encapsulation, I had the thread as an inner class. You can of course use Runnable as well. As @Trevor Tippins pointed out, it's also good to flag the thread as daemon thread.

I also used Google Chart and had actually another ShowStatisticsServlet that would rad the XML file and turn the data into a nice Chart. The servlet would not depends on the filter, but only on the XML file, so both were actually decoupled. The XML file can be created as a temporary file with File.createTempFile. (Another variant would be of course to keep all data in memory, but storing the data was handy for us to backup the results of perf. tests and analyze them later)

Some colleague claimed that the synchronization in the Statistics object would "kill" the app performance, but in practice it was really neglectable. The overhead to dump the file as well, given that it was done each 10 sec or so.

Hope it helps, or give you some ideas.

PS: And as @William Louth commented, you should write such infrastructure code only if you can't solve your issue with an existing solution. In my case, I was also benchmarking the internal time of my code, not only the complete request processing time.

ewernli
You might want to make the dump thread a daemon so it doesn't prevent the container from shutting down cleanly.
Trevor Tippins
@Trevor Tippins Good point. Added.
ewernli
The interesting bit would be the inside of PeriodicDumpStat. But I'm no fan of threads in web applications.
Tommy
@Tommy if you don't want a thread you can say that you dump the file after, say, 10, 20, 30, etc. measures; what you want to avoid is to dump it after *each* measure. After you've dump the file, you reset the stats. The code to dump the stat depends on the format of the data you use, so it's hard to provide anything useful for that.
ewernli