Hello, there are several profiling and monitoring tools which help you to find bottlenecks in your application. I would like to propose yet another pretty simple tool which does not intend to compete with professional ones.
The idea is very simple. All functions used in application are devided into
several big categories: SERVLET, ACTION, JSP, WEB, EJB, DAO.
ActionServlet class of Struts is modified to define SERVLET and JSP
categories (log4j can be used for this purpose) and add >>> and <<<
log messages for each request. Here I have subclass the ActionServlet:
private static Category s_oProf = null;
private static Category s_oProfJSP = null;
protected void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
String sURI = request.getRequestURI();
if (s_oProf.isInfoEnabled()) {
NDC.push(Long.toString(System.currentTimeMillis()));
s_oProf.info(">>> " + sURI);
}
try {
super.process(request, response);
} finally {
if (s_oProf.isInfoEnabled()) {
s_oProf.info("<<< " + sURI);
NDC.pop();
}
}
}
Pushing of timestamp in NDC helps you to differentiate between requests.
It works fine if web and ejb container is the same process.
Similar procedure for JSP pages:
protected void processActionForward(ActionForward forward,
ActionMapping mapping,
ActionForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
if (forward == null)
return;
boolean bJsp = forward.getPath().endsWith(".jsp");
if (s_oProfJSP.isInfoEnabled() && bJsp) {
s_oProfJSP.info(">>> " + forward.getPath());
}
try {
super.processActionForward(forward, mapping, formInstance,
request, response);
} finally {
if (s_oProfJSP.isInfoEnabled() && bJsp) {
s_oProfJSP.info("<<< " + forward.getPath());
}
}
}
Action class is also modified to include
if (s_oProf.isInfoEnabled()) {
s_oProf.info(">>> " + this.getClass().getName());
}
at the beginning of execute() method with corresponding
try {
.....
} finally {
if (s_oProf.isInfoEnabled()) {
s_oProf.info("<<< " + this.getClass().getName());
}
}
This we can cover all servlet requests and requests for JSP pages.
All other functions can be proceeded with the help of AspectJ
without of touching of source code. Example of such file is attached to this
mail.
Now we need to configure log4j:
og4j.category.STARTUP=INFO, MONITOR
log4j.additivity.STARTUP=false
log4j.category.SERVLET=INFO, MONITOR
log4j.additivity.SERVLET=false
log4j.category.ACTION=INFO, MONITOR
log4j.additivity.ACTION=false
log4j.category.JSP=INFO, MONITOR
log4j.additivity.JSP=false
log4j.category.WEB=INFO, MONITOR
log4j.additivity.WEB=false
log4j.category.EJB=INFO, MONITOR
log4j.additivity.EJB=false
# Configuration of MONITOR appender
log4j.appender.MONITOR=org.apache.log4j.RollingFileAppender
log4j.appender.MONITOR.File=${log.dir}/monitor.log
log4j.appender.MONITOR.MaxFileSize=5MB
log4j.appender.MONITOR.MaxBackupIndex=10
log4j.appender.MONITOR.layout=org.apache.log4j.PatternLayout
log4j.appender.MONITOR.layout.ConversionPattern=%-10r %-10c <%1x> - %m\n
and start logging in ActionServlet.init()
PropertyConfigurator.configure(sConfigPath);
// Get "profiler" category
s_oProf = Category.getCategory("SERVLET");
s_oProfJSP = Category.getCategory("JSP");
s_oProfStartup = Category.getCategory("STARTUP");
// Start profiling
if (s_oProfStartup.isInfoEnabled()) {
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy
'at' H:mm:ss");
NDC.push("*************");
s_oProfStartup.info("Monitoring started on " +
formatter.format(new Date()));
NDC.pop();
}
Now we can start the application and after some time have a look at monitor
files.
I have attached a sample monitor.log file and a profiler for watching the
results.
The profiler can be started with
java -jar profiler.jar
You should open the monitor file and you will see a tree with all requests.
You can walk through tree items and locate the chewing pigs.
Dmitri Valdin
profiler.ZIP
Description: Zip compressed data
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
