Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Servlet Profiling

What is the best way to undertake Servlet profiling?

In particular I am looking for a solution that can show the execution times of the method calls within the servlet.

I am running the Servlet within a Tomcat environment.

I have tried VisualVM but it only allows me to see the method calls from the Tomcat thread rather than the Servlets themselves.

like image 766
Tobias M Avatar asked Mar 12 '10 04:03

Tobias M


3 Answers

I have used JProfiler for profiling, they have support for many different servers and gives very good control and good reports. However it's a commercial application, though you can get an evaluation version. You can take a look at open source profilers as well, though I have not used any of these and can't say how good or bad they are.

Edit I assume you understand how profiling works, the profiler will do some instrumentation and attach an agent to the JVM, all this affects performance. So never ever use it in production environment.

like image 167
saugata Avatar answered Sep 21 '22 06:09

saugata


A manual approach to this could be creating a filter to the servlets in question, you can then measure the time it takes for all the executions to complete and store them somewhere. This is good because the overhead for profiling the calls is just as much as the code you write in the filter, I also found it very useful to find the pages and servlets that takes longer to completely load.

This is how filters work

  • Url is called
  • Filter enters and stores called url and current time (startTime)
  • Filter invokes destination servlet(s)
  • Servlet executes (servlet, page or jsp)
  • Control returns to the filter execution time is: currentTime - startTime
  • Log or store the data obtained for future comparisson (ie store it to a csv file)
  • Filter ends

To do so create a class that implements the javax.servlet.Filter interface.

public class ProfilingFilter implements Filter {
  public void init(FilterConfig fc){}
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain){
    long startTime = System.currentTimeInMillis();
    String servletName = ((HttpServletRequest) req)..getPathInfo();
    chain.doFilter(req, resp);
    long executionTime = System.currentTimeInMillis()-startTime;
    // Implement the following to store or handle the data.
    logData(servletName, executionTime);
  }
}

Now add it to your web.xml

<filter>
  <filter-name>profilingFilter</filter-name>
  <filter-class>com.awesome.ProfilingFilter</filter-class>
</filter>

And finally the mapping:

<filter-mapping>
  <filter-name>profilingFilter</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>

Be aware that this will filter EVERYTHING so you will profile, html, jsp, servlets, images, and what not.

We found this very useful to find what exactly in the application was taking too much time to respond or was extremely heavy.

You can even enable this in production for a day or two to get real data, the punch on performance will be just as big as your code spent to save the profiling data.

Some ideas: Store your statistics in a map inside servlet-context and then have another servlet display those statistics. that way you dont even need to access the disk.

like image 30
Ed_Zero Avatar answered Sep 21 '22 06:09

Ed_Zero


Why don't you use JConsole - which exposes MBeans. Your container application will probably expose some useful fields relavent to your servlet - and if it doesn't you can create your own MBeans.

like image 31
Amir Afghani Avatar answered Sep 20 '22 06:09

Amir Afghani