Author: kkolinko Date: Wed Jun 20 08:36:07 2012 New Revision: 1351991 URL: http://svn.apache.org/viewvc?rev=1351991&view=rev Log: For https://issues.apache.org/bugzilla/show_bug.cgi?id=50306 Improve StuckThreadDetectionValve: - Add getStuckThreadNames() method, callable through JMX - Add thread ids to the log messages
I also removed the @author tag, as that is against our policies. Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/valves/StuckThreadDetectionValve.java tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml tomcat/trunk/webapps/docs/config/valve.xml Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties?rev=1351991&r1=1351990&r2=1351991&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties Wed Jun 20 08:36:07 2012 @@ -47,8 +47,8 @@ sslValve.certError=Failed to process cer sslValve.invalidProvider=The SSL provider specified on the connector associated with this request of [{0}] is invalid. The certificate data could not be processed. #Stuck thread detection Valve -stuckThreadDetectionValve.notifyStuckThreadDetected=Thread "{0}" has been active for {1} milliseconds (since {2}) to serve the same request for {4} and may be stuck (configured threshold for this StuckThreadDetectionValve is {5} seconds). There is/are {3} thread(s) in total that are monitored by this Valve and may be stuck. -stuckThreadDetectionValve.notifyStuckThreadCompleted=Thread "{0}" was previously reported to be stuck but has completed. It was active for approximately {1} milliseconds.{2,choice,0#|0< There is/are still {2} thread(s) that are monitored by this Valve and may be stuck.} +stuckThreadDetectionValve.notifyStuckThreadDetected=Thread "{0}" (id={6}) has been active for {1} milliseconds (since {2}) to serve the same request for {4} and may be stuck (configured threshold for this StuckThreadDetectionValve is {5} seconds). There is/are {3} thread(s) in total that are monitored by this Valve and may be stuck. +stuckThreadDetectionValve.notifyStuckThreadCompleted=Thread "{0}" (id={3}) was previously reported to be stuck but has completed. It was active for approximately {1} milliseconds.{2,choice,0#|0< There is/are still {2} thread(s) that are monitored by this Valve and may be stuck.} # HTTP status reports http.100=The client may continue ({0}). Modified: tomcat/trunk/java/org/apache/catalina/valves/StuckThreadDetectionValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/StuckThreadDetectionValve.java?rev=1351991&r1=1351990&r2=1351991&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/StuckThreadDetectionValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/StuckThreadDetectionValve.java Wed Jun 20 08:36:07 2012 @@ -35,12 +35,8 @@ import org.apache.juli.logging.LogFactor import org.apache.tomcat.util.res.StringManager; /** - * This valve allows to detect requests that take a long time to process, which might - * indicate that the thread that is processing it is stuck. - * Based on code proposed by TomLu in Bugzilla entry #50306 - * - * @author slaurent - * + * This valve allows to detect requests that take a long time to process, which + * might indicate that the thread that is processing it is stuck. */ public class StuckThreadDetectionValve extends ValveBase { @@ -123,10 +119,14 @@ public class StuckThreadDetectionValve e if (log.isWarnEnabled()) { String msg = sm.getString( "stuckThreadDetectionValve.notifyStuckThreadDetected", - monitoredThread.getThread().getName(), Long.valueOf(activeTime), + monitoredThread.getThread().getName(), + Long.valueOf(activeTime), monitoredThread.getStartTime(), Integer.valueOf(numStuckThreads), - monitoredThread.getRequestUri(), Integer.valueOf(threshold)); + monitoredThread.getRequestUri(), + Integer.valueOf(threshold), + String.valueOf(monitoredThread.getThread().getId()) + ); // msg += "\n" + getStackTraceAsString(trace); Throwable th = new Throwable(); th.setStackTrace(monitoredThread.getThread().getStackTrace()); @@ -134,13 +134,15 @@ public class StuckThreadDetectionValve e } } - private void notifyStuckThreadCompleted(String threadName, - long activeTime, int numStuckThreads) { + private void notifyStuckThreadCompleted(CompletedStuckThread thread, + int numStuckThreads) { if (log.isWarnEnabled()) { String msg = sm.getString( "stuckThreadDetectionValve.notifyStuckThreadCompleted", - threadName, Long.valueOf(activeTime), - Integer.valueOf(numStuckThreads)); + thread.getName(), + Long.valueOf(thread.getTotalActiveTime()), + Integer.valueOf(numStuckThreads), + String.valueOf(thread.getId())); // Since the "stuck thread notification" is warn, this should also // be warn log.warn(msg); @@ -180,7 +182,7 @@ public class StuckThreadDetectionValve e activeThreads.remove(key); if (monitoredThread.markAsDone() == MonitoredThreadState.STUCK) { completedStuckThreadsQueue.add( - new CompletedStuckThread(monitoredThread.getThread().getName(), + new CompletedStuckThread(monitoredThread.getThread(), monitoredThread.getActiveTimeInMillis())); } } @@ -207,8 +209,7 @@ public class StuckThreadDetectionValve e completedStuckThread != null; completedStuckThread = completedStuckThreadsQueue.poll()) { int numStuckThreads = stuckCount.decrementAndGet(); - notifyStuckThreadCompleted(completedStuckThread.getName(), - completedStuckThread.getTotalActiveTime(), numStuckThreads); + notifyStuckThreadCompleted(completedStuckThread, numStuckThreads); } } @@ -227,6 +228,16 @@ public class StuckThreadDetectionValve e return result; } + public String[] getStuckThreadNames() { + List<String> nameList = new ArrayList<String>(); + for (MonitoredThread monitoredThread : activeThreads.values()) { + if (monitoredThread.isMarkedAsStuck()) { + nameList.add(monitoredThread.getThread().getName()); + } + } + return nameList.toArray(new String[nameList.size()]); + } + private static class MonitoredThread { /** @@ -278,10 +289,12 @@ public class StuckThreadDetectionValve e private static class CompletedStuckThread { private final String threadName; + private final long threadId; private final long totalActiveTime; - public CompletedStuckThread(String threadName, long totalActiveTime) { - this.threadName = threadName; + public CompletedStuckThread(Thread thread, long totalActiveTime) { + this.threadName = thread.getName(); + this.threadId = thread.getId(); this.totalActiveTime = totalActiveTime; } @@ -289,6 +302,10 @@ public class StuckThreadDetectionValve e return this.threadName; } + public long getId() { + return this.threadId; + } + public long getTotalActiveTime() { return this.totalActiveTime; } Modified: tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml?rev=1351991&r1=1351990&r2=1351991&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml (original) +++ tomcat/trunk/java/org/apache/catalina/valves/mbeans-descriptors.xml Wed Jun 20 08:36:07 2012 @@ -496,10 +496,15 @@ writeable="false"/> <attribute name="stuckThreadIds" - description="IDs of the thread currently considered stuck. Each ID can then be used with the ThreadMXBean to retrieve data about it." + description="IDs of the threads currently considered stuck. Each ID can then be used with the Threading MBean to retrieve data about it." type="long[]" writeable="false"/> + <attribute name="stuckThreadNames" + description="Names of the threads currently considered stuck." + type="java.lang.String[]" + writeable="false"/> + <attribute name="threshold" description="Duration in seconds after which a request is considered as stuck" type="int"/> Modified: tomcat/trunk/webapps/docs/config/valve.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=1351991&r1=1351990&r2=1351991&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/valve.xml (original) +++ tomcat/trunk/webapps/docs/config/valve.xml Wed Jun 20 08:36:07 2012 @@ -1444,9 +1444,11 @@ indicate that the thread that is processing it is stuck.</p> <p>When such a request is detected, the current stack trace of its thread is written to Tomcat log with a WARN level.</p> - <p>The IDs of the stuck threads are available through JMX in the - <code>stuckThreadIds</code> attribute. The JVM Thread MBean can then be used to - retrieve other information about each stuck thread (name, stack trace...).</p> + <p>The IDs and names of the stuck threads are available through JMX in the + <code>stuckThreadIds</code> and <code>stuckThreadNames</code> attributes. + The IDs can be used with the standard Threading JVM MBean + (<code>java.lang:type=Threading</code>) to retrieve other information + about each stuck thread.</p> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org