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]>