0

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.

ewernli
  • 38,045
  • 5
  • 92
  • 123
Tommy
  • 4,011
  • 9
  • 37
  • 59
  • Can you elaborate more? An answer 'static variable' would be probably only a result of misunderstanding of what you need. – Jaroslav Záruba May 25 '10 at 23:13
  • "this is a high volume application; low overhead is essential." Then why code this yourself when there are tools on the market road tested for such environments with proper tooling, data management and visualizations. What happens when someone asks for X, Y, and Z. Focus on the application development and consider using tooling created by performance experts to ease the initial effort and future maintenance. Some of these tools even offer a headless (w/out UI) runtime with an Open API for you to integrate it into your own management dashboard. Check out http://opencore.jinspired.com – William Louth May 26 '10 at 11:10
  • @William Louth Your comment is valuable. You could write it as an answer, I think. – ewernli May 26 '10 at 15:11
  • Side note: You should use `nanoTime()` to measure elapsed time, not `currentTimeMillis()`. See Kevin Bourrillion's [answer](http://stackoverflow.com/questions/1770010/how-do-i-measure-time-elapsed-in-java/1776053#1776053) for background on this. – Pascal Thivent May 26 '10 at 23:57
  • There is a trade-off between low overhead and low footprint. I'm not looking to reinvent the wheel or anything. Just a simple way to measure these to things. – Tommy May 27 '10 at 17:30

1 Answers1

1

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
  • 38,045
  • 5
  • 92
  • 123
  • 1
    You might want to make the dump thread a daemon so it doesn't prevent the container from shutting down cleanly. – Trevor Tippins May 26 '10 at 07:27
  • The interesting bit would be the inside of PeriodicDumpStat. But I'm no fan of threads in web applications. – Tommy May 27 '10 at 17:32
  • @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 May 27 '10 at 22:47
  • @Trevor Tippin I have been wondering why tomcat hasn't been shutting down for ages, its so simple, stupid default ThreadFactory not making daemon threads, Thanks. – Nathan Feger Mar 03 '11 at 15:07