Add logging and JMX support to JSP unloading.
authorrjung <rjung@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 2 Nov 2010 12:14:43 +0000 (12:14 +0000)
committerrjung <rjung@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 2 Nov 2010 12:14:43 +0000 (12:14 +0000)
Also need to make getContent() public in
FastRemovalDequeue to support logging.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1030014 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/jasper/compiler/JspRuntimeContext.java
java/org/apache/jasper/resources/LocalStrings.properties
java/org/apache/jasper/servlet/JspServlet.java
java/org/apache/jasper/servlet/mbeans-descriptors.xml
java/org/apache/jasper/util/FastRemovalDequeue.java
webapps/docs/changelog.xml

index 215b29d..d7f9290 100644 (file)
@@ -69,6 +69,11 @@ public final class JspRuntimeContext {
      */
     private AtomicInteger jspReloadCount = new AtomicInteger(0);
 
+    /*
+     * Counts how many times JSPs have been unloaded in this webapp.
+     */
+    private AtomicInteger jspUnloadCount = new AtomicInteger(0);
+
     /**
      * Preload classes required at runtime by a JSP servlet so that
      * we don't get a defineClassInPackage security exception.
@@ -158,6 +163,10 @@ public final class JspRuntimeContext {
 
         if (options.getMaxLoadedJsps() > 0) {
             jspQueue = new FastRemovalDequeue<JspServletWrapper>(options.getMaxLoadedJsps());
+            if (log.isDebugEnabled()) {
+                log.debug(Localizer.getMessage("jsp.message.jsp_queue_created",
+                                               "" + options.getMaxLoadedJsps(), context.getContextPath()));
+            }
         }
 
         /* Init parameter is in seconds, locally we use milliseconds */
@@ -229,9 +238,17 @@ public final class JspRuntimeContext {
      * @return an unloadHandle that can be pushed to front of queue at later execution times.
      * */
     public FastRemovalDequeue<JspServletWrapper>.Entry push(JspServletWrapper jsw) {
+        if (log.isTraceEnabled()) {
+            log.trace(Localizer.getMessage("jsp.message.jsp_added",
+                                           jsw.getJspUri(), context.getContextPath()));
+        }
         FastRemovalDequeue<JspServletWrapper>.Entry entry = jspQueue.push(jsw);
         JspServletWrapper replaced = entry.getReplaced();
         if (replaced != null) {
+            if (log.isDebugEnabled()) {
+                log.debug(Localizer.getMessage("jsp.message.jsp_removed_excess",
+                                               jsw.getJspUri(), context.getContextPath()));
+            }
             unloadJspServletWrapper(replaced);
         }
         return entry;
@@ -243,6 +260,11 @@ public final class JspRuntimeContext {
      * @param unloadHandle the unloadHandle for the jsp.
      * */
     public void makeYoungest(FastRemovalDequeue<JspServletWrapper>.Entry unloadHandle) {
+        if (log.isTraceEnabled()) {
+            JspServletWrapper jsw = unloadHandle.getContent();
+            log.trace(Localizer.getMessage("jsp.message.jsp_queue_update",
+                                           jsw.getJspUri(), context.getContextPath()));
+        }
         jspQueue.moveFirst(unloadHandle);
     }
     
@@ -320,6 +342,36 @@ public final class JspRuntimeContext {
         return jspReloadCount.intValue();
     }
 
+    /**
+     * Gets the number of JSPs that are in the JSP limiter queue
+     *
+     * @return The number of JSPs (in the webapp with which this JspServlet is
+     * associated) that are in the JSP limiter queue
+     */
+    public int getJspQueueLength() {
+        if (jspQueue != null) {
+            return jspQueue.getSize();
+        }
+        return -1;
+    }
+
+    /**
+     * Increments the JSP unload counter.
+     */
+    public void incrementJspUnloadCount() {
+        jspUnloadCount.incrementAndGet();
+    }
+
+    /**
+     * Gets the number of JSPs that have been unloaded.
+     *
+     * @return The number of JSPs (in the webapp with which this JspServlet is
+     * associated) that have been unloaded
+     */
+    public int getJspUnloadCount() {
+        return jspUnloadCount.intValue();
+    }
+
 
     /**
      * Method used by background thread to check the JSP dependencies
@@ -523,6 +575,7 @@ public final class JspRuntimeContext {
         synchronized(jsw) {
             jsw.destroy();
         }
+        jspUnloadCount.incrementAndGet();
     }
 
 
@@ -531,6 +584,14 @@ public final class JspRuntimeContext {
      */
     public void checkUnload() {
 
+        if (log.isTraceEnabled()) {
+            int queueLength = -1;
+            if (jspQueue != null) {
+                queueLength = jspQueue.getSize();
+            }
+            log.trace(Localizer.getMessage("jsp.message.jsp_unload_check",
+                                           context.getContextPath(), "" + jsps.size(), "" + queueLength));
+        }
         long now = System.currentTimeMillis();
         if (jspIdleTimeout > 0) {
             long unloadBefore = now - jspIdleTimeout;
@@ -539,6 +600,11 @@ public final class JspRuntimeContext {
                 JspServletWrapper jsw = (JspServletWrapper)wrappers[i];
                 synchronized(jsw) {
                     if (jsw.getLastUsageTime() < unloadBefore) {
+                        if (log.isDebugEnabled()) {
+                            log.debug(Localizer.getMessage("jsp.message.jsp_removed_idle",
+                                                           jsw.getJspUri(), context.getContextPath(),
+                                                           "" + (now-jsw.getLastUsageTime())));
+                        }
                         if (jspQueue != null) {
                             jspQueue.remove(jsw.getUnloadHandle());
                         }
index 616eea5..cae2529 100644 (file)
@@ -472,3 +472,11 @@ jsp.error.bug48498=Unable to display JSP extract. Probably due to an XML parser
 
 # UniqueAttributesImpl
 jsp.error.duplicateqname=An attribute with duplicate qualified name [{0}] was found. Attribute qualified names must be unique within an element.
+
+# JSP unloading handling
+jsp.message.jsp_queue_created=Created jsp queue with length {0} for context [{1}]
+jsp.message.jsp_added=Adding JSP for path [{0}] to queue of context [{1}]
+jsp.message.jsp_queue_update=Updating JSP for path [{0}] in queue of context [{1}]
+jsp.message.jsp_removed_excess=Removing excess JSP for path [{0}] from queue of context [{1}]
+jsp.message.jsp_removed_idle=Removing idle JSP for path [{0}] in context [{1}] after {2} seconds");
+jsp.message.jsp_unload_check=Checking JSPs for unload in context [{0}], JSP count: {1} queue length: {2}
index a071d60..f95c0aa 100644 (file)
@@ -192,6 +192,32 @@ public class JspServlet extends HttpServlet implements PeriodicEventListener {
 
 
     /**
+     * Gets the number of JSPs that are in the JSP limiter queue
+     *
+     * <p>This info may be used for monitoring purposes.
+     *
+     * @return The number of JSPs (in the webapp with which this JspServlet is
+     * associated) that are in the JSP limiter queue
+     */
+    public int getJspQueueLength() {
+        return this.rctxt.getJspQueueLength();
+    }
+
+
+    /**
+     * Gets the number of JSPs that have been unloaded.
+     *
+     * <p>This info may be used for monitoring purposes.
+     *
+     * @return The number of JSPs (in the webapp with which this JspServlet is
+     * associated) that have been unloaded
+     */
+    public int getJspUnloadCount() {
+        return this.rctxt.getJspUnloadCount();
+    }
+
+
+    /**
      * <p>Look for a <em>precompilation request</em> as described in
      * Section 8.4.2 of the JSP 1.2 Specification.  <strong>WARNING</strong> -
      * we cannot use <code>request.getParameter()</code> for this, because
index d678381..d784537 100644 (file)
           description="The number of JSPs that have been reloaded"
                  type="int"/>
 
+    <attribute   name="jspUnloadCount"
+          description="The number of JSPs that have been unloaded"
+                 type="int"/>
+
+    <attribute   name="jspQueueLength"
+          description="The length of the JSP queue (if enabled via maxLoadedJsps)"
+                 type="int"/>
+
   </mbean>
 
-</mbeans-descriptors>
\ No newline at end of file
+</mbeans-descriptors>
index 97de61d..74a65fd 100644 (file)
@@ -272,7 +272,7 @@ public class FastRemovalDequeue<T> {
             this.valid = valid;
         }
 
-        private final T getContent() {
+        public final T getContent() {
             return content;
         }
 
index 69249a1..f81f217 100644 (file)
         Add support for unloading JSPs that have not been requested for a
         long time using the new parameter <code>jspIdleTimeout</code>. (rjung)
       </add>
+      <add>
+        Add logging and JMX support to JSP unloading. (rjung)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Cluster">