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.
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.
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With