diff --git a/src/java/com/oracle/ateam/threadlogic/doc/README b/src/java/com/oracle/ateam/threadlogic/doc/README index 1d52177..0ec2682 100644 --- a/src/java/com/oracle/ateam/threadlogic/doc/README +++ b/src/java/com/oracle/ateam/threadlogic/doc/README @@ -1,17 +1,25 @@ - ThreadLogic v2.0 + ThreadLogic v2.5 -

ThreadLogic (version 2.0)

+

ThreadLogic (version 2.5.2)

-

Date: Sept 1, 2014

+

Date: Sept 21, 2018

-Note: This is the version 2.0 release of the software + Note: This is the version 2.5 release of the software -This is a release version. + This is a release version. -

Changes in this release

+

Changes in this release

+
    +
  1. Handle OpenJDK Thread Dumps
  2. +
  3. Added advisories to recognize Tomcat threads
  4. +
  5. Added advisories to recognize Datastax threads
  6. +
  7. Added advisories to recognize Apache Logging threads
  8. +
+ +

Changes since 2.0

  1. Enhanced to read context data for SOA 12c, if you want to know how to generate the diagnostic dumps with context data using WLST, please read this blog
  2. Enhanced to display composite/flow id in thread list, it will display composite/flow name and instance/flow id
  3. @@ -31,9 +39,9 @@ This is a release version.
  4. Oracle SOA Socket Adapter
  5. Oracle SOA MSMQ Adapter
  6. Oracle SOA UMS Adapter
  7. - +
  8. Fixed thread parser failed to parse thread dump generated using WLST dump sample for SOA 12c
  9. -
  10. Fixed thread dump line number not display properly after reading the context data
  11. +
  12. Fixed thread dump line number not display properly after reading the context data
  13. Fixed multiple keywords in the advisories not displayed properly
  14. Fixed IBM JDK Parser when parsing thread info pattern matching failed
@@ -70,6 +78,4 @@ This is a release version.
  • Excluded AQ adapter threads from Oracle Framework thread group
  • - -Report problems, ask questions and submit suggestions in the ThreadLogic forum - +Report problems, ask questions and submit suggestions in the ThreadLogic Issues github Page diff --git a/src/java/com/oracle/ateam/threadlogic/doc/README.html b/src/java/com/oracle/ateam/threadlogic/doc/README.html index 1d52177..659fe99 100644 --- a/src/java/com/oracle/ateam/threadlogic/doc/README.html +++ b/src/java/com/oracle/ateam/threadlogic/doc/README.html @@ -1,17 +1,25 @@ - ThreadLogic v2.0 + ThreadLogic v2.5 -

    ThreadLogic (version 2.0)

    +

    ThreadLogic (version 2.5.2)

    -

    Date: Sept 1, 2014

    +

    Date: Sept 21, 2018

    -Note: This is the version 2.0 release of the software +Note: This is the version 2.5 release of the software This is a release version.

    Changes in this release

    +
      +
    1. Handle OpenJDK Thread Dumps
    2. +
    3. Added advisories to recognize Tomcat threads
    4. +
    5. Added advisories to recognize Datastax threads
    6. +
    7. Added advisories to recognize Apache Logging threads
    8. +
    + +

    Changes since 2.0

    1. Enhanced to read context data for SOA 12c, if you want to know how to generate the diagnostic dumps with context data using WLST, please read this blog
    2. Enhanced to display composite/flow id in thread list, it will display composite/flow name and instance/flow id
    3. @@ -31,9 +39,9 @@

      Changes in this release

    4. Oracle SOA Socket Adapter
    5. Oracle SOA MSMQ Adapter
    6. Oracle SOA UMS Adapter
    7. - +
    8. Fixed thread parser failed to parse thread dump generated using WLST dump sample for SOA 12c
    9. -
    10. Fixed thread dump line number not display properly after reading the context data
    11. +
    12. Fixed thread dump line number not display properly after reading the context data
    13. Fixed multiple keywords in the advisories not displayed properly
    14. Fixed IBM JDK Parser when parsing thread info pattern matching failed
    @@ -70,6 +78,4 @@

    Changes since 0.9

  • Excluded AQ adapter threads from Oracle Framework thread group
  • - -Report problems, ask questions and submit suggestions in the ThreadLogic forum - +Report problems, ask questions and submit suggestions in the ThreadLogic Issues github Page diff --git a/src/java/com/oracle/ateam/threadlogic/parsers/AbstractDumpParser.java b/src/java/com/oracle/ateam/threadlogic/parsers/AbstractDumpParser.java index 6e1c9ab..46e5ba2 100644 --- a/src/java/com/oracle/ateam/threadlogic/parsers/AbstractDumpParser.java +++ b/src/java/com/oracle/ateam/threadlogic/parsers/AbstractDumpParser.java @@ -1,9 +1,9 @@ /** * Copyright (c) 2012 egross, sabha. - * + * * ThreadLogic - parses thread dumps and provides analysis/guidance * It is based on the popular TDA tool. Thank you! - * + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at @@ -82,10 +82,10 @@ /** * abstract dump parser class, contains all generic dump parser stuff, which * doesn't have any jdk specific parsing code. - * + * * All Dump Parser should extend from this class as it already provides a basic * parsing interface. - * + * * @author irockel */ public abstract class AbstractDumpParser implements DumpParser, Serializable { @@ -120,14 +120,15 @@ public abstract class AbstractDumpParser implements DumpParser, Serializable { protected static final int HOTSPOT_VM = 0; protected static final int JROCKIT_VM = 1; protected static final int IBM_VM = 2; - protected static final int UNKNOWN_VM = 3; - protected static final int[] VM_ID_LIST = {HOTSPOT_VM, JROCKIT_VM, IBM_VM, UNKNOWN_VM}; - protected static final String[] JVM_VENDOR_LIST = {"Sun Hotspot", "Oracle JRockit", "IBM", "Unknown"}; + protected static final int OPENJDK_VM = 3; + protected static final int UNKNOWN_VM = 4; + protected static final int[] VM_ID_LIST = {HOTSPOT_VM, JROCKIT_VM, IBM_VM, OPENJDK_VM, UNKNOWN_VM}; + protected static final String[] JVM_VENDOR_LIST = {"Sun Hotspot", "Oracle JRockit", "IBM", "OpenJDK", "Unknown"}; protected String jvmVendor = JVM_VENDOR_LIST[JVM_VENDOR_LIST.length - 1]; protected String jvmVersion; private static Logger theLogger = CustomLogger.getLogger(AbstractDumpParser.class.getSimpleName()); - + // Used for deserialization public AbstractDumpParser() { lineChecker = new LineChecker(); @@ -150,7 +151,7 @@ protected void initVars() { /** * strip the dump string from a given path - * + * * @param path * the treepath to check * @return dump string, if proper tree path, null otherwise. @@ -167,7 +168,7 @@ protected String getDumpStringFromTreePath(TreePath path) { /** * find long running threads. - * + * * @param root * the root node to use for the result. * @param dumpStore @@ -186,7 +187,7 @@ public void findLongRunningThreads(DefaultMutableTreeNode root, Map dumpStore, T /** * merge the given dumps. - * + * * @param root * the root node to use for the result. * @param dumpStore @@ -267,14 +268,14 @@ protected void diffDumps(String prefix, DefaultMutableTreeNode root, Map dumpSto } } else if (dumpName.startsWith("JMX Thread Dump") || dumpName.startsWith("Clipboard")) { // Dump generated via jmx mbean server connection in JConsole Plugin function - // Format of generated dump: + // Format of generated dump: // JMX Thread Dump of com.jrockit.mc.rjmx.internal.MCMBeanServerConnection@341c80d4 // at 2013-10-06 16:17:50 tdiID = Integer.parseInt(dumpName.substring(dumpName.lastIndexOf(" ") + 1).replaceAll(":", "").trim()); } - // Its possible the thread dump got expanded + // Its possible the thread dump got expanded // and its internal threads/threadgroups also got selected // Ignore such selection if (tdiID == null) { @@ -508,7 +509,7 @@ protected void diffDumps(String prefix, DefaultMutableTreeNode root, Map dumpSto /** * count lines of input string. - * + * * @param input * @return line count */ @@ -526,7 +527,7 @@ private int countLines(String input) { /** * generate statistical information concerning the merge on long running * thread detection. - * + * * @param keys * the dump node keys * @param prefix @@ -579,7 +580,7 @@ private String getStatInfo(Vector keys, String prefix, int minOccurence, int thr /** * fix the monitor links for proper navigation to the monitor in the right * dump. - * + * * @param fixString * the string to fix * @param dumpName @@ -595,7 +596,7 @@ private String fixMonitorLinks(String fixString, String dumpName) { /** * create a tree node with the provided information - * + * * @param top * the parent node the new node should be added to. * @param title @@ -621,7 +622,7 @@ protected void createNode(DefaultMutableTreeNode top, String title, String info, * create a category entry for a category (categories are "Monitors", * "Threads waiting", e.g.). A ThreadInfo instance will be created with the * passed information. - * + * * @param category * the category the node should be added to. * @param title @@ -652,7 +653,7 @@ protected void addToCategory(DefaultMutableTreeNode category, ThreadInfo info) { * create a category entry for a category (categories are "Monitors", * "Threads waiting", e.g.). A ThreadInfo instance will be created with the * passed information. - * + * * @param category * the category the node should be added to. * @param tdi @@ -686,7 +687,7 @@ protected void addToCategory(DefaultMutableTreeNode category, ThreadDumpInfo tdi /** * get the stream to parse - * + * * @return stream or null if none is set up */ protected LineNumberReader getBis() { @@ -695,14 +696,14 @@ protected LineNumberReader getBis() { /** * parse the thread tokens for table display. - * + * * @param title */ protected abstract String[] getThreadTokens(String title); /** * set the stream to parse - * + * * @param bis * the stream */ @@ -720,7 +721,7 @@ public void setDumpHistogramCounter(int value) { /** * retrieve the next node for adding histogram information into the tree. - * + * * @param root * the root to use for search. * @return node to use for append. @@ -751,7 +752,7 @@ public void close() throws IOException { /** * get the maximum size for the mark buffer while reading the log file stream. - * + * * @return size, default is 16KB. */ protected int getMarkSize() { @@ -760,7 +761,7 @@ protected int getMarkSize() { /** * set the maximum mark size. - * + * * @param markSize * the size to use, default is 16KB. */ @@ -771,7 +772,7 @@ protected void setMarkSize(int markSize) { /** * specifies the maximum amounts of lines to check if the dump is followed by * a class histogram or a deadlock. - * + * * @return the amount of lines to check, defaults to 10. */ protected int getMaxCheckLines() { @@ -803,7 +804,7 @@ public void setDm(DateMatcher dm) { /** * dump the monitor information - * + * * @param catMonitors * @param catMonitorsLocks * @param mmap @@ -910,7 +911,7 @@ protected int[] dumpBlockingMonitors(DefaultMutableTreeNode catLockingTree, Moni /** * check threads in given thread dump and add appropriate custom categories * (if any defined). - * + * * @param tdi * the thread dump info object. */ @@ -1240,10 +1241,10 @@ private void updateChildCount(DefaultMutableTreeNode threadOrMonitorNode, boolea ThreadInfo mi = (ThreadInfo) threadOrMonitorNode.getUserObject(); - // Don't mark the thread category as having Lot of Waiters - // if the threads are waiting for java.util.concurrent.locks.AbstractQueuedSynchronizer + // Don't mark the thread category as having Lot of Waiters + // if the threads are waiting for java.util.concurrent.locks.AbstractQueuedSynchronizer /* - * + * * "pool-3-thread-8" id=91 idx=0x168 tid=22940 prio=5 alive, parked, native_blocked -- Parking to wait for: java/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject@0x140211ee0 at jrockit/vm/Locks.park0(J)V(Native Method) @@ -1254,7 +1255,7 @@ private void updateChildCount(DefaultMutableTreeNode threadOrMonitorNode, boolea at java/util/concurrent/LinkedBlockingQueue.take(LinkedBlockingQueue.java:399) at java/util/concurrent/ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) at java/util/concurrent/ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) - * + * */ if (!mi.getName().contains("java/util/concurrent/locks/AbstractQueuedSynchronizer") && ThreadDumpInfo.areALotOfWaiting(count)) { mi.setALotOfWaiting(true); @@ -1401,7 +1402,7 @@ boolean checkForDuplicateThreadItem(Map directChildMap, DefaultMutableTreeNode n return false; } - protected String getNextLine() throws IOException { + protected String getNextLine() throws IOException { return getBis().readLine(); } @@ -1416,7 +1417,7 @@ public boolean hasMoreDumps() { /** * parse the next thread dump from the stream passed with the constructor. - * + * * @returns null if no more thread dumps were found. */ public MutableTreeNode parseNext() { @@ -1584,7 +1585,7 @@ public MutableTreeNode parseNext() { * "Workmanager: , Version: 0, Scheduled=false, Started=false, Wait time: 0 ms * " id=1509 idx=0x84 tid=10346 prio=10 alive, sleeping, native_waiting, daemon */ - // Check if the thread contains "Workmanager:" and ending with " ms" + // Check if the thread contains "Workmanager:" and ending with " ms" // In that case, rerun the pattern to get correct thread label String additionalLines = readAheadForWMThreadLabels(line); if (additionalLines.length() > line.length()) { @@ -1594,7 +1595,7 @@ public MutableTreeNode parseNext() { // We are starting a group of lines for a different // thread // First, flush state for the previous thread (if - // any) + // any) concurrentSyncsFlag = false; if (content != null) { @@ -1689,7 +1690,7 @@ public MutableTreeNode parseNext() { // position. getBis().reset(); } - * + * */ //getBis().mark(getMarkSize()); @@ -1770,7 +1771,7 @@ public MutableTreeNode parseNext() { // first the locks // We need to reset the stack trace for those threads that are holders of locks - // previously we set the stack trace to be empty as the ownership info was present in a different thread + // previously we set the stack trace to be empty as the ownership info was present in a different thread // that is blocked and not directly in the owner thread Iterator iterLocks = threadsInMap[MonitorMap.LOCK_THREAD_POS].keySet().iterator(); while (iterLocks.hasNext()) { @@ -1779,7 +1780,7 @@ public MutableTreeNode parseNext() { String stackTrace = (String) threadsInMap[MonitorMap.LOCK_THREAD_POS].get(threadOwner); if (stackTrace == null) { theLogger.finest("ThreadOwner :" + threadOwner + ", owner stack is null"); - + // Search for the owner of the lock ThreadInfo ownerThread = overallTDI.getThreadByName(threadOwner); if (ownerThread != null) { @@ -1880,7 +1881,7 @@ public MutableTreeNode parseNext() { + (line != null ? "Last line read was \"" + line + "\". \n" : ""), "Error during Parsing Thread Dump", JOptionPane.ERROR_MESSAGE); retry = true; - } catch (InterruptedIOException e) { + } catch (InterruptedIOException e) { } catch (IOException e) { e.printStackTrace(); } @@ -1896,7 +1897,7 @@ public MutableTreeNode parseNext() { * @param line * @return * @throws java.io.IOException - * + * */ protected String readAheadForWMThreadLabels(String line) throws IOException { String currentLine = line.trim(); @@ -1904,14 +1905,14 @@ protected String readAheadForWMThreadLabels(String line) throws IOException { return line; } - // Read further the next line and add it to the current thread title line + // Read further the next line and add it to the current thread title line String newLine = null; do { lineCounter++; newLine = getNextLine(); } while (newLine.trim().equals("")); - currentLine = line + newLine; + currentLine = line + newLine; return currentLine; } @@ -1929,7 +1930,7 @@ protected String readAheadForWMThreadLabels(String line) throws IOException { * [0x94130000,0x94e68168,0x95060000) PSPermGen total 16384K, used 13145K * [0x90130000, 0x91130000, 0x94130000) object space 16384K, 80% used * [0x90130000,0x90e06610,0x91130000) - * + * * @param threadDump * @return * @throws java.io.IOException @@ -2006,9 +2007,9 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept // //id ECID RID Context Values Matcher threadContextInfoMatcher = null; - - //Derek Kam: 12c has an addional elapse time column, the common columns between 12c and 11g are id, ECID and RID, - //so I removed the Context Values, it should be enough to identify the context info header. + + //Derek Kam: 12c has an addional elapse time column, the common columns between 12c and 11g are id, ECID and RID, + //so I removed the Context Values, it should be enough to identify the context info header. Pattern threadContextInfoPattern = Pattern.compile(".*(" + THREAD_CONTEXT_INFO + "|id\\s*ECID\\s*RID).*"); @@ -2020,7 +2021,7 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept line = line.trim(); - // We have reached start of a new thread dump, so stop + // We have reached start of a new thread dump, so stop if (this.lineChecker.getFullDump(line) != null) { theLogger.finest("Breaking now as we hit Full Dump for Current Line: " + line); return false; @@ -2036,7 +2037,7 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept } else { reachedExactEndOfDump = true; getBis().mark(getMarkSize()); - } + } } */ @@ -2062,9 +2063,9 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept // There will be one statistic line per thread // Keep going till we reach Thread Context Info banner - // then start parsing ECID and other Context data per thread + // then start parsing ECID and other Context data per thread if (!foundContextData) { - // Found begining marker of Thread Context Info + // Found begining marker of Thread Context Info foundContextData = (line.indexOf(THREAD_CONTEXT_INFO) > 0); //skip just found Thread Context Info banner and proceed to actual data... @@ -2098,7 +2099,7 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept // Parse new thread context info String[] entries = line.trim().split("\\s+"); contextValBuf = new StringBuffer(); - + //Derek Kam: 12c has five column, Elapsed/ms is new in 12c if (entries.length==5) { switch (entries.length) { @@ -2152,16 +2153,16 @@ protected boolean checkThreadDumpContextData(ThreadDumpInfo tdi) throws IOExcept tdi.addThreadContextData(threadId, contextValBuf.toString()); } - // We have hit the end marker for the Thread Context Info + // We have hit the end marker for the Thread Context Info // finish parsing finished = true; return foundContextData; - } - - + } + + /** * check if any dead lock information is logged in the stream - * + * * @param threadDump * which tree node to add the histogram. */ @@ -2577,20 +2578,20 @@ public void createLockInfo(ThreadInfo thread) { /* * "Thread-1" prio=6 tid=0x186f4c00 nid=0x1318 waiting on condition - * [0x189ff000] java.lang.Thread.State: TIMED_WAITING (sleeping) + * [0x189ff000] java.lang.Thread.State: TIMED_WAITING (sleeping) * at java.lang.Thread.sleep(Native Method) - * at MyTest.doSomething(MyTest.java:24) - * at MyTest.run(MyTest.java:18) - * - locked <0x04292a30> (a java.lang.Object) + * at MyTest.doSomething(MyTest.java:24) + * at MyTest.run(MyTest.java:18) + * - locked <0x04292a30> (a java.lang.Object) * at java.lang.Thread.run(Thread.java:619) - * + * * "Thread-0" prio=6 tid=0x186f0400 nid=0x2b28 in Object.wait() [0x1896f000] - * java.lang.Thread.State: WAITING (on object monitor) - * java.lang.Object.wait(Native Method) - * - waiting on <0x04292a30> (a java.lang.Object) - * at java.lang.Object.wait(Object.java:485) - * at MyTest.run(MyTest.java:15) - * - locked <0x04292a30> (a java.lang.Object) + * java.lang.Thread.State: WAITING (on object monitor) + * java.lang.Object.wait(Native Method) + * - waiting on <0x04292a30> (a java.lang.Object) + * at java.lang.Object.wait(Object.java:485) + * at MyTest.run(MyTest.java:15) + * - locked <0x04292a30> (a java.lang.Object) * at java.lang.Thread.run(Thread.java:619) */ @@ -2611,22 +2612,22 @@ public void createLockInfo(ThreadInfo thread) { // the lock first but released it which was then obtained by Thread-1 /* * "Thread-0" id=12 idx=0x50 tid=9704 prio=5 alive, waiting, native_blocked - * -- Waiting for notification on: java/lang/Object@0x101F0B40[fat lock] - * at jrockit/vm/Threads.waitForNotifySignal(JLjava/lang/Object;)Z(Native Method) - * at java/lang/Object.wait(J)V(Native Method) - * at java/lang/Object.wait(Object.java:485) at MyTest.run(MyTest.java:15) - * ^-- Lock released while waiting: java/lang/Object@0x101F0B40[fat lock] - * at java/lang/Thread.run(Thread.java:619) - * at jrockit/vm/RNI.c2java(IIIII)V(Native Method) + * -- Waiting for notification on: java/lang/Object@0x101F0B40[fat lock] + * at jrockit/vm/Threads.waitForNotifySignal(JLjava/lang/Object;)Z(Native Method) + * at java/lang/Object.wait(J)V(Native Method) + * at java/lang/Object.wait(Object.java:485) at MyTest.run(MyTest.java:15) + * ^-- Lock released while waiting: java/lang/Object@0x101F0B40[fat lock] + * at java/lang/Thread.run(Thread.java:619) + * at jrockit/vm/RNI.c2java(IIIII)V(Native Method) * -- end of trace - * + * * "Thread-1" id=13 idx=0x54 tid=7608 prio=5 alive, sleeping, native_waiting - * at java/lang/Thread.sleep(J)V(Native Method) - * at MyTest.doSomething(MyTest.java:24) - * at MyTest.run(MyTest.java:18) - * ^-- Holding lock: java/lang/Object@0x101F0B40[fat lock] - * at java/lang/Thread.run(Thread.java:619) - * at jrockit/vm/RNI.c2java(IIIII)V(Native Method) + * at java/lang/Thread.sleep(J)V(Native Method) + * at MyTest.doSomething(MyTest.java:24) + * at MyTest.run(MyTest.java:18) + * ^-- Holding lock: java/lang/Object@0x101F0B40[fat lock] + * at java/lang/Thread.run(Thread.java:619) + * at jrockit/vm/RNI.c2java(IIIII)V(Native Method) * -- end of trace */ // But we dont have to discount it from the owned locks as JRockit logs it @@ -2664,7 +2665,7 @@ public static ArrayList getTrailingEntryAfterPattern(String data, String java.lang.Thread.State: BLOCKED at weblogic.socket.DevPollSocketMuxer.processSockets(DevPollSocketMuxer.java:92) - waiting to lock <4de8b404> (a java.lang.String) owned by "ExecuteThread: '2' for queue: 'weblogic.socket.Muxer'" t@242 - * + * */ entry = entry.replaceAll(" owned by .*", "").trim(); diff --git a/src/java/com/oracle/ateam/threadlogic/parsers/DumpParserFactory.java b/src/java/com/oracle/ateam/threadlogic/parsers/DumpParserFactory.java index 928429c..07c58f9 100644 --- a/src/java/com/oracle/ateam/threadlogic/parsers/DumpParserFactory.java +++ b/src/java/com/oracle/ateam/threadlogic/parsers/DumpParserFactory.java @@ -1,9 +1,9 @@ /** * Copyright (c) 2012 egross, sabha. - * + * * ThreadLogic - parses thread dumps and provides analysis/guidance * It is based on the popular TDA tool. Thank you! - * + * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at @@ -45,7 +45,7 @@ /** * Factory for the dump parsers. - * + * * @author irockel */ public class DumpParserFactory { @@ -59,7 +59,7 @@ private DumpParserFactory() { /** * get the singleton instance of the factory - * + * * @return singleton instance */ public static DumpParserFactory get() { @@ -74,7 +74,7 @@ public static DumpParserFactory get() { * parses the given logfile for thread dumps and return a proper jdk parser * (either for Sun VM's or for JRockit/Bea VM's) and initializes the * DumpParser with the stream. - * + * * @param dumpFileStream * the file stream to use for dump parsing. * @param threadStore @@ -102,23 +102,23 @@ public DumpParser getDumpParserForLogfile(InputStream dumpFileStream, Map thread while (bis.ready() && (currentDumpParser == null)) { bis.mark(readAheadLimit); String line = bis.readLine(); - dm.checkForDateMatch(line); + dm.checkForDateMatch(line); if (dm.isDefaultMatches()) { dateEntry = line; foundDate = true; - + // Save the very last date entry before we hit the Thread Dump Markers lastSavedDm = dm; } - + if (line.trim().equals("")) continue; - + if (WrappedSunJDKParser.checkForSupportedThreadDump(line)) { currentDumpParser = new WrappedSunJDKParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); // } else if (HotspotParser.checkForSupportedThreadDump(line)) { -// currentDumpParser = new HotspotParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); +// currentDumpParser = new HotspotParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); } else if (JrockitParser.checkForSupportedThreadDump(line) || HotspotParser.checkForSupportedThreadDump(line)) { // Derek Kam: Need to handle thread dump generated using // WLST for 12c @@ -129,7 +129,9 @@ public DumpParser getDumpParserForLogfile(InputStream dumpFileStream, Map thread currentDumpParser = new HotspotParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); } else if (line2.trim().indexOf("Oracle JRockit") >= 0) { currentDumpParser = new JrockitParser(bis, threadStore, bis.getLineNumber(), lastSavedDm); - } + } else if (line2.trim().indexOf("OpenJDK") >= 0) { + currentDumpParser = new OpenJDKParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); + } } } else if (IBMJDKParser.checkForSupportedThreadDump(line)) { currentDumpParser = new IBMJDKParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm); @@ -137,13 +139,13 @@ public DumpParser getDumpParserForLogfile(InputStream dumpFileStream, Map thread int supportedJvmType = FallbackParser.checkForSupportedThreadDump(line); if (supportedJvmType < 0) continue; - + // Found some sort of match against the FallbackParser currentDumpParser = new FallbackParser(bis, threadStore, bis.getLineNumber(), withCurrentTimeStamp, startCounter, lastSavedDm, supportedJvmType); } } - + if ((currentDumpParser != null) && (bis != null)) { bis.reset(); } diff --git a/src/java/com/oracle/ateam/threadlogic/parsers/OpenJDKParser.java b/src/java/com/oracle/ateam/threadlogic/parsers/OpenJDKParser.java new file mode 100644 index 0000000..b36bdf3 --- /dev/null +++ b/src/java/com/oracle/ateam/threadlogic/parsers/OpenJDKParser.java @@ -0,0 +1,595 @@ +/** + * Copyright (c) 2012 egross, sabha. + * + * ThreadLogic - parses thread dumps and provides analysis/guidance + * It is based on the popular TDA tool. Thank you! + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v2.1 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + */ +/* + * SunJDKParser.java + * + * This file is part of TDA - Thread Dump Analysis Tool. + * + * TDA is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * TDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Lesser GNU General Public License for more details. + * + * You should have received a copy of the Lesser GNU General Public License + * along with TDA; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * $Id: SunJDKParser.java,v 1.47 2010-01-03 14:23:09 irockel Exp $ + */ +package com.oracle.ateam.threadlogic.parsers; + +import com.oracle.ateam.threadlogic.HistogramInfo; +import com.oracle.ateam.threadlogic.ThreadLogic; +import com.oracle.ateam.threadlogic.ThreadDumpInfo; +import com.oracle.ateam.threadlogic.categories.TreeCategory; +import com.oracle.ateam.threadlogic.monitors.MonitorMap; +import com.oracle.ateam.threadlogic.utils.CustomLogger; +import com.oracle.ateam.threadlogic.utils.DateMatcher; +import com.oracle.ateam.threadlogic.utils.HistogramTableModel; +import com.oracle.ateam.threadlogic.utils.IconFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.Map; +import java.util.Vector; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.MutableTreeNode; + +/** + * Parses SunJDK Thread Dumps. Also parses SAP and HP Dumps. Needs to be closed + * after use (so inner stream is closed). + * + * @author irockel + */ +public class OpenJDKParser extends AbstractDumpParser { + + private int counter = 1; + private boolean foundClassHistograms = false; + private boolean withCurrentTimeStamp = false; + + private static Logger theLogger = CustomLogger.getLogger(OpenJDKParser.class.getSimpleName()); + + /** + * Creates a new instance of SunJDKParser + */ + public OpenJDKParser(LineNumberReader bis, Map threadStore, int lineCounter, boolean withCurrentTimeStamp, + int startCounter, DateMatcher dm) { + super(bis, dm); + this.threadStore = threadStore; + this.withCurrentTimeStamp = withCurrentTimeStamp; + this.lineCounter = lineCounter; + this.counter = startCounter; + this.lineChecker = new LineChecker(); + this.lineChecker.setFullDumpPattern("(.*Full thread dump.*)"); + this.lineChecker.setAtPattern("(.*at.*)"); + this.lineChecker.setThreadStatePattern("(.*java.lang.Thread.State.*)"); + this.lineChecker.setLockedOwnablePattern("(.*Locked ownable synchronizers:.*)"); + this.lineChecker.setWaitingOnPattern("(.*- waiting on.*)"); + this.lineChecker.setParkingToWaitPattern("(.*- parking to wait.*)"); + this.lineChecker.setWaitingToPattern("(.*- waiting to.*)"); + this.lineChecker.setLockedPattern("(.*- locked.*)"); + this.lineChecker.setEndOfDumpPattern(".*(VM Periodic Task Thread|Suspend Checker Thread|Full thread dump|END OF THREAD DUMP|JNI global references|object space|^\\d\\d\\d\\d-\\d{1,2}-\\d{1,2}\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}|).*"); + this.lineChecker.setExactEndOfDumpPattern(".*(VM Periodic Task Thread|Suspend Checker Thread|JNI global references|object space|).*"); + this.setJvmVendor(JVM_VENDOR_LIST[OPENJDK_VM]); + + parseJvmVersion(bis); + } + + /** + * @returns true, if a class histogram was found and added during parsing. + */ + public boolean isFoundClassHistograms() { + return (foundClassHistograms); + } + + public MutableTreeNode parseNext() { + this.mmap = new MonitorMap(); + return super.parseNext(); + } + + /** + * add a monitor link for monitor navigation + * + * @param line + * containing monitor + */ + protected String linkifyMonitor(String line) { + try { + if (line != null && line.indexOf('<') >= 0) { + String begin = line.substring(0, line.indexOf('<')); + String monitor = line.substring(line.indexOf('<'), line.indexOf('>') + 1); + String end = line.substring(line.indexOf('>') + 1); + monitor = monitor.replaceAll("<", "<"); + monitor = monitor.substring(0, monitor.length() - 1) + ">"; + return (begin + monitor + end); + } else if (line != null && line.indexOf('@') >= 0) { + String begin = line.substring(0, line.indexOf('@') + 1); + String monitor = line.substring(line.indexOf('@')); + monitor = monitor.replaceAll("@", "@\">"); + monitor = monitor.substring(0, monitor.length() - 1) + ""; + return (begin + monitor); + } else { + return (line); + } + } catch(Exception e) { + return null; + } + } + + /** + * add a monitor link for monitor navigation + * + * @param line + * containing monitor + */ + public String linkifyDeadlockInfo(String line) { + if (line != null && line.indexOf("Ox") >= 0) { + String begin = line.substring(0, line.indexOf("0x")); + int objectBegin = line.lastIndexOf("0x"); + int monitorBegin = line.indexOf("0x"); + String monitorHex = line.substring(monitorBegin, monitorBegin + 10); + + String monitor = line.substring(objectBegin, objectBegin + 10); + String end = line.substring(line.indexOf("0x") + 10); + + monitor = "\">" + monitorHex + ""; + return (begin + monitor + end); + } else { + return (line); + } + } + + /** + * checks for the next class histogram and adds it to the tree node passed + * + * @param threadDump + * which tree node to add the histogram. + */ + public boolean checkForClassHistogram(DefaultMutableTreeNode threadDump) throws IOException { + HistogramTableModel classHistogram = parseNextClassHistogram(getBis()); + + if (classHistogram.getRowCount() > 0) { + addHistogramToDump(threadDump, classHistogram); + } + + return (classHistogram.getRowCount() > 0); + } + + /** + * checks for the Lock Chains and adds it to the tree node passed + * + * @param threadDump + * which tree node to add the lock chain info. + */ + public boolean checkForLockChains(DefaultMutableTreeNode threadDump) throws IOException { + return false; + } + + + private void addHistogramToDump(DefaultMutableTreeNode threadDump, HistogramTableModel classHistogram) { + DefaultMutableTreeNode catHistogram; + HistogramInfo hi = new HistogramInfo("Class Histogram of Dump", classHistogram); + catHistogram = new DefaultMutableTreeNode(hi); + threadDump.add(catHistogram); + } + + /** + * parses the next class histogram found in the stream, uses the max check + * lines option to check how many lines to parse in advance. + *

    + * This could be called from parseLoggcFile, which is outside our normal + * calling stream. Thus, we have to pass in the LineNumberReader. However, to + * handle a WrappedSunJDKParser, we have to use getNextLine() if possible. + * + * @param bis + * the stream to read. + */ + private HistogramTableModel parseNextClassHistogram(LineNumberReader bis) throws IOException { + boolean finished = false; + boolean found = false; + HistogramTableModel classHistogram = new HistogramTableModel(); + int maxLinesCounter = 0; + + boolean isNormalBis = bis == getBis(); + + while (bis.ready() && !finished) { + String line = (isNormalBis) ? getNextLine().trim() : bis.readLine().trim(); + if (!found && !line.equals("")) { + if (line.startsWith("num #instances #bytes class name")) { + found = true; + } else if (maxLinesCounter >= getMaxCheckLines()) { + finished = true; + } else { + maxLinesCounter++; + } + } else if (found) { + if (line.startsWith("Total ")) { + // split string. + String newLine = line.replaceAll("(\\s)+", ";"); + String[] elems = newLine.split(";"); + classHistogram.setBytes(Long.parseLong(elems[2])); + classHistogram.setInstances(Long.parseLong(elems[1])); + finished = true; + } else if (!line.startsWith("-------")) { + // removed blank, breaks splitting using blank... + String newLine = line.replaceAll("", ""); + + // split string. + newLine = newLine.replaceAll("(\\s)+", ";"); + String[] elems = newLine.split(";"); + + if (elems.length == 4) { + classHistogram.addEntry(elems[3].trim(), Integer.parseInt(elems[2].trim()), + Integer.parseInt(elems[1].trim())); + } else { + classHistogram.setIncomplete(true); + finished = true; + } + + } + } + } + + return (classHistogram); + } + + /** + * Heap PSYoungGen total 6656K, used 3855K [0xb0850000, 0xb0f50000, + * 0xb4130000) eden space 6144K, 54% used [0xb0850000,0xb0b97740,0xb0e50000) + * from space 512K, 97% used [0xb0ed0000,0xb0f4c5c0,0xb0f50000) to space 512K, + * 0% used [0xb0e50000,0xb0e50000,0xb0ed0000) PSOldGen total 15552K, used + * 13536K [0x94130000, 0x95060000, 0xb0850000) object space 15552K, 87% used + * [0x94130000,0x94e68168,0x95060000) PSPermGen total 16384K, used 13145K + * [0x90130000, 0x91130000, 0x94130000) object space 16384K, 80% used + * [0x90130000,0x90e06610,0x91130000) + * + * @param threadDump + * @return + * @throws java.io.IOException + * + public boolean checkThreadDumpStatData(ThreadDumpInfo tdi) throws IOException { + boolean finished = false; + boolean found = false; + StringBuffer hContent = new StringBuffer(); + int heapLineCounter = 0; + int lines = 0; + + while (getBis().ready() && !finished) { + String line = getNextLine(); + if (!found && !line.equals("")) { + if (line.trim().startsWith("Heap")) { + found = true; + } else if (lines >= getMaxCheckLines()) { + finished = true; + } else { + lines++; + } + } else if (found) { + if (heapLineCounter < 7) { + hContent.append(line).append("\n"); + } else { + finished = true; + } + heapLineCounter++; + } + } + if (hContent.length() > 0) { + tdi.setHeapInfo(new HeapInfo(hContent.toString())); + theLogger.finest("Found heap info:" + hContent.toString()); + } + + return (found); + } + * */ + + /** + * check if any dead lock information is logged in the stream + * + * @param threadDump + * which tree node to add the histogram. + */ + public int checkForDeadlocks(DefaultMutableTreeNode threadDump) throws IOException { + boolean finished = false; + boolean found = false; + int deadlocks = 0; + int lineCounter = 0; + StringBuffer dContent = new StringBuffer(); + TreeCategory deadlockCat = new TreeCategory("Deadlocks", IconFactory.DEADLOCKS); + DefaultMutableTreeNode catDeadlocks = new DefaultMutableTreeNode(deadlockCat); + boolean first = true; + + while (getBis().ready() && !finished) { + String line = getNextLine(); + + if (!found && !line.equals("")) { + if (line.trim().startsWith("Found one Java-level deadlock")) { + found = true; + dContent.append(""); + dContent.append("Found one Java-level deadlock"); + dContent.append("


    \n");
    +        } else if (lineCounter >= getMaxCheckLines()) {
    +          finished = true;
    +        } else {
    +          lineCounter++;
    +        }
    +      } else if (found) {
    +        if (line.startsWith("Found one Java-level deadlock")) {
    +          if (dContent.length() > 0) {
    +            deadlocks++;
    +            addToCategory(catDeadlocks, "Deadlock No. " + (deadlocks), null, dContent.toString(), 0, false);
    +          }
    +          dContent = new StringBuffer();
    +          dContent.append("
    "); + dContent.append("Found one Java-level deadlock"); + dContent.append("
    \n");
    +          first = true;
    +        } else if ((line.indexOf("Found") >= 0) && (line.endsWith("deadlocks.") || line.endsWith("deadlock."))) {
    +          finished = true;
    +        } else if (line.startsWith("=======")) {
    +          // ignore this line
    +        } else if (line.indexOf(" monitor 0x") >= 0) {
    +          dContent.append(linkifyDeadlockInfo(line));
    +          dContent.append("\n");
    +        } else if (line.indexOf("Java stack information for the threads listed above") >= 0) {
    +          dContent.append("

    "); + dContent.append("Java stack information for the threads listed above"); + dContent.append("
    ");
    +          first = true;
    +        } else if ((line.indexOf("- waiting on") >= 0) || (line.indexOf("- waiting to") >= 0)
    +            || (line.indexOf("- locked") >= 0) || (line.indexOf("- parking to wait") >= 0)) {
    +
    +          dContent.append(linkifyMonitor(line));
    +          dContent.append("\n");
    +
    +        } else if (line.trim().startsWith("\"")) {
    +          dContent.append("
    "); + if (first) { + first = false; + } else { + dContent.append("
    "); + } + dContent.append(""); + dContent.append(line); + dContent.append("
    ");
    +        } else {
    +          dContent.append(line);
    +          dContent.append("\n");
    +        }
    +      }
    +    }
    +    if (dContent.length() > 0) {
    +      deadlocks++;
    +      addToCategory(catDeadlocks, "Deadlock No. " + (deadlocks), null, dContent.toString(), 0, false);
    +    }
    +
    +    if (deadlocks > 0) {
    +      threadDump.add(catDeadlocks);
    +      ((ThreadDumpInfo) threadDump.getUserObject()).setDeadlocks((TreeCategory) catDeadlocks.getUserObject());
    +      deadlockCat.setName("Deadlocks (" + deadlocks + (deadlocks == 1 ? " deadlock)" : " deadlocks)"));
    +    }
    +
    +    return (deadlocks);
    +  }
    +
    +  /**
    +   * parses a loggc file stream and reads any found class histograms and adds
    +   * the to the dump store
    +   *
    +   * @param loggcFileStream
    +   *          the stream to read
    +   * @param root
    +   *          the root node of the dumps.
    +   */
    +  public void parseLoggcFile(InputStream loggcFileStream, DefaultMutableTreeNode root) {
    +	LineNumberReader bis = new LineNumberReader(new InputStreamReader(loggcFileStream));
    +    Vector histograms = new Vector();
    +
    +    try {
    +      while (bis.ready()) {
    +        bis.mark(getMarkSize());
    +        String nextLine = bis.readLine();
    +        if (nextLine.startsWith("num   #instances    #bytes  class name")) {
    +          bis.reset();
    +          histograms.add(parseNextClassHistogram(bis));
    +        }
    +      }
    +
    +      // now add the found histograms to the tree.
    +      for (int i = histograms.size() - 1; i >= 0; i--) {
    +        DefaultMutableTreeNode dump = getNextDumpForHistogram(root);
    +        if (dump != null) {
    +          addHistogramToDump(dump, (HistogramTableModel) histograms.get(i));
    +        }
    +      }
    +    } catch (IOException ex) {
    +      ex.printStackTrace();
    +    }
    +  }
    +
    +  /**
    +   * generate thread info token for table view.
    +   *
    +   * @param name
    +   *          the thread info.
    +   * @return thread tokens.
    +   */
    +  public String[] getThreadTokens(String name) {
    +
    +    // Try for pattern matching
    +    // Example: "pool-107-thread-25" prio=10 tid=0x000000004b7de800 nid=0x13b9 waiting on condition [0x0000000077305000]
    +
    +    String patternMask = "^.*\"([^\\\"]+)\".*tid=([^ ]+|).*nid=([^ ]+) *([^\\[]*).*";
    +    name = name.replace("- Thread t@", "tid=");
    +
    +    String[] tokens = new String[] {};
    +    Pattern p = null;
    +
    +    try {
    +      p = Pattern.compile(patternMask);
    +      Matcher m = p.matcher(name);
    +
    +      m.matches();
    +
    +      tokens = new String[7];
    +      tokens[0] = m.group(1); // name
    +      // tokens[1] = m.group(4); // prio
    +      tokens[1] = m.group(2); // tid
    +      tokens[2] = m.group(3); // nid
    +      tokens[3] = m.group(4); // State
    +
    +      // Always treat the tid as a hexa decimal
    +      if (!tokens[1].startsWith("0x"))
    +        tokens[1] = "0x" + tokens[1];
    +
    +    } catch(Exception e) {
    +
    +      // Failure, try different pattern matching
    +      // Example: "pool-107-thread-25" nid=0x13b9 state=WAIITING
    +
    +      patternMask = "^.*\"([^\\\"]+)\".*nid=([^ ]+) *state=([^\\[]*).*";
    +
    +      try {
    +
    +        p = Pattern.compile(patternMask);
    +        Matcher m = p.matcher(name);
    +
    +        m.matches();
    +        tokens = new String[7];
    +        tokens[0] = m.group(1); // name
    +        tokens[2] = m.group(2); // nid
    +        tokens[3] = m.group(3); // State
    +      } catch(Exception e2) {
    +      theLogger.finest("WARNING!! Unable to parse partial Thread Tokens with name:" + name);
    +      //e.printStackTrace();
    +      return doHardParsing(name);
    +      }
    +    }
    +
    +    return (tokens);
    +  }
    +
    +  /**
    +   * check and parse manually the thread label
    +   *
    +   * @param nameEntry
    +   *          the thread name line
    +   */
    +   private String[] doHardParsing(String nameEntry) {
    +
    +      String[] tokens = new String[4];
    +      int index = nameEntry.indexOf("\"", 1);
    +      if (index > 1) {
    +        tokens[0] = nameEntry.substring(1, index);
    +      } else {
    +        tokens[0] = nameEntry.substring(1);
    +        return tokens;
    +      }
    +
    +      String remainingLabel = nameEntry.substring(index + 1).trim();
    +      String[] remainingTokens = remainingLabel.replace("daemon ","").trim().split(" ");
    +
    +      // If there are more fields in the thread name
    +      // like: "pool-107-thread-25" prio=10 tid=0x000000004b7de800 nid=0x13b9 waiting on condition [0x0000000077305000]
    +
    +      if (remainingTokens.length >= 3) {
    +        for(int i = 1; i < remainingTokens.length; i++) {
    +          if (i == 3)
    +            break;
    +
    +          String label = remainingTokens[i].replaceAll(".*=", "");
    +          //if (i == 1) // tid
    +          if (remainingTokens[i].startsWith("tid") || remainingTokens[i].startsWith("id")) //Derek Kam :  Added id as the thread ID
    +            tokens[1] = label;
    +          //else if (i == 2) // nid
    +          if (remainingTokens[i].startsWith("nid"))
    +            tokens[2] = label;
    +        }
    +
    +
    +        for(int i = 3; i < remainingTokens.length; i++) {
    +          if (remainingTokens[i].startsWith("[0"))
    +            break;
    +
    +          tokens[3] = tokens[3] + " " + remainingTokens[i];
    +        }
    +      } else {
    +        // Hotspot thread dump dumped using JMX does not have priority or other data fields..
    +        // Example: "SwingWorker-pool-3-thread-6" nid=52 state=WAITING
    +        for(int i = 0; i < remainingTokens.length; i++) {
    +
    +          String label = remainingTokens[i].replaceAll(".*=", "");
    +          //if (i == 1) // tid
    +          if (remainingTokens[i].startsWith("tid") || remainingTokens[i].startsWith("id")) //Derek Kam :  Added id as the thread ID
    +            tokens[1] = label;
    +          //else if (i == 2) // nid
    +          else if (remainingTokens[i].startsWith("nid"))
    +            tokens[2] = label;
    +          else
    +            tokens[3] = tokens[3] + " " + remainingTokens[i];
    +        }
    +
    +      }
    +
    +      // Always treat the tid as a hexa decimal - Derek Kam:  Commented these 2 lines, treat the tid data as it is, no conversion.
    +//      if (tokens[1] != null && !tokens[1].startsWith("0x"))
    +//        tokens[1] = "0x" + tokens[1];
    +
    +      return tokens;
    +   }
    +
    +  /**
    +   * check if the passed logline contains the beginning of a sun jdk thread
    +   * dump.
    +   *
    +   * @param logLine
    +   *          the line of the logfile to test
    +   * @return true, if the start of a sun thread dump is detected.
    +   */
    +  public static boolean checkForSupportedThreadDump(String logLine) {
    +    return (logLine.trim().indexOf("Full thread dump") >= 0);
    +  }
    +
    +  /**
    +   * @param bis the LineNumberReader
    +   */
    +  protected void parseJvmVersion(LineNumberReader bis) {
    +    int count = 0;
    +    try {
    +      bis.reset();
    +      while (bis.ready() && count++ < 15) {
    +        String line = bis.readLine();
    +        if (line != null) {
    +          int index = line.indexOf("OpenJDK");
    +          if (index > 0) {
    +            super.setJvmVersion(line.substring(index).trim().replaceAll(":", ""));
    +            theLogger.info("JVM Version:" + line);
    +            return;
    +          }
    +        }
    +      }
    +    } catch(Exception e) { }
    +
    +  }
    +
    +}
    diff --git a/src/java/com/oracle/ateam/threadlogic/resources/AdvisoryMap.xml b/src/java/com/oracle/ateam/threadlogic/resources/AdvisoryMap.xml
    index 87655de..3da91da 100644
    --- a/src/java/com/oracle/ateam/threadlogic/resources/AdvisoryMap.xml
    +++ b/src/java/com/oracle/ateam/threadlogic/resources/AdvisoryMap.xml
    @@ -14,7 +14,7 @@ Advisory is used to tag threads that match or display certain characteristics
     The behavior might be coming from the thread (name/stack/state) or a combination of conditions (like multiple threads blocked for same lock or it got marked as STUCK etc). Each of the advisory has an associated health level that can be used to filter/analyze or build on for further analysis.
     
     Each Advisory entry has a Name, Health, Keyword (pattern to search against), Description and Advice
    -The Name is used as short id/reference to an Advice 
    +The Name is used as short id/reference to an Advice
     The Health can be one of the following - IGNORE, NORMAL, WATCH, WARNING, FATAL (increasing level of severity)
     The Thread with a certain set of advisories is marked with the health level that matches the most severe of its tagged advisories.
     Similarly, the most severe advisory across multiple threads in the thread group are promoted to the group and so on to the Thread dump
    @@ -29,17 +29,17 @@ Example:
     		Using Native IO via Select or Poll
     		Ignore
     	
    -  
    +
     Use . (period) instead of / package paths in the keyword entry.
     Use wildcard as needed; Use . (period character) for escaping $, ?, _ etc.
     
     The advisory is a match for a thread when the keyword search against the thread is successful.
    -There can be multiple keywords separated by a ", ". 
    +There can be multiple keywords separated by a ", ".
     For example:
     
     
       DB Execute
    -  WATCH    
    +  WATCH
       PreparedStatement.execute, Statement.executeQuery
       Executing operation or query on DB
       Check/Monitor Database SQL Executions if it takes longer and also check for socket connection disruption to database if thread continues to show same pattern
    @@ -50,12 +50,12 @@ In above example, there are 2 keywords (PreparedStatement.execute and Statement.
     The next entry is the Descrp which is a just a textual description of the advisory
     The last entry is the Advice - as to actions or solutions can be applied.
     
    -For multi-line pattern, use PatternA.*PatternB to match against all lines that start off 
    +For multi-line pattern, use PatternA.*PatternB to match against all lines that start off
     with PatternA with some content in the middle and ending with PatternB.
     Use with caution as it can do greedy grab of everything within the specified patterns.
     Example:
     
    -  
    +
     The Name of the advice can be used within the GroupDefns to downgrade certain advisories for specific thread groups.
     Ensure the Advice Name in AdvisoryMap matches with the AdvisoryId inside GroupDefns.
     Example:
    @@ -72,7 +72,7 @@ Example:
       
         DB Execute
         Socket Read
    -          
    +  
     
     
     In the above example, DB Execute and Socket Read Advisories are excluded for the thread group: Oracle AQ Adapter
    @@ -84,7 +84,7 @@ If '&' is really required, use &
     -->
     
     
    -
       
         WLS Synchronous JMS Receiver
    @@ -96,7 +96,7 @@ xmlns="http://java.net/projects/threadlogic">
       
         JMS Producer Flow control
         WARNING
    -    weblogic.jms.client.JMSProducer.doFlowControl		         
    +    weblogic.jms.client.JMSProducer.doFlowControl
         Producer message flow is controlled (slowed down)
         Try to maintain equilibrium between producers and consumers by speeding up consumers or slowing down producers; Tune the flow control configuration parameters as needed 
       
    @@ -239,7 +239,7 @@ xmlns="http://java.net/projects/threadlogic">
         afjca15.AbstractResourceAdapter.endpointDeactivation
         IWay Adapter Endpoint Deactivation invoked
         IWay Adapter endpoint is getting deactivated, there would be service disruption,; Ensure the call completes by checking in successive thread dumps
    -    
    +  
       
         Stellent WCM
         NORMAL
    @@ -288,7 +288,7 @@ xmlns="http://java.net/projects/threadlogic">
         com.bea.wli.sb.pipeline.RouterCallback.onReceiveResponse
         OSB handling response
         Normal OSB response handling
    -    
    +  
       
         OSB Proxy waiting for response
         WATCH
    @@ -302,7 +302,7 @@ xmlns="http://java.net/projects/threadlogic">
         com.bea.wli.sb.service.resultcache.ResultCache.get
         OSB attempting to lookup cached service response from Coherence layer
         OSB is attempting to check for a cached service response from Coherence layer,; Should return immediately and not get into waiting or blocked state
    -    
    +  
       
         OSB Service Response save in cache 
         NORMAL
    @@ -316,21 +316,21 @@ xmlns="http://java.net/projects/threadlogic">
         stages.transform.runtime.JavaCalloutRuntimeStep
         OSB Proxy service invoking Java Callout
         Normal java callout activity
    -    
    +  
       
         XPath Contention
         WARNING
         a java.lang.Class for org.apache.xmlbeans.impl.store.Path, org.apache.xmlbeans.impl.store.Path.getCompiledPath
         Apache XMLBeans might be hitting static synchronized method during xpath execution
         Apply Bug #9727796 if threads appear blocked in xpath compilation
    -   
    +  
       
         WLS JMS Paging
         WARNING
         mesaging.kernel.internal.PagingImpl
         WebLogic JMS paging messages to disk
         
    -       WLS might have started paging message to disk either because consumers cannot keep up with producers and messages have started accumulating increasing memory pressure or for temporary storage due to delayed delivery; Paging will slow down performance; Increase, speed up or tune consumers or use flow controls/quotas to slow down producers and in-flow rates; Or increase number of servers to share the load. 
    +       WLS might have started paging message to disk either because consumers cannot keep up with producers and messages have started accumulating increasing memory pressure or for temporary storage due to delayed delivery; Paging will slow down performance; Increase, speed up or tune consumers or use flow controls/quotas to slow down producers and in-flow rates; Or increase number of servers to share the load.
         
       
       
    @@ -412,7 +412,7 @@ xmlns="http://java.net/projects/threadlogic">
       
       
         DB Execute
    -    WATCH    
    +    WATCH
         Statement.execute, Statement.fetch
         Executing operation or query on DB
         Check/Monitor Database SQL Executions if it takes longer and also check for socket connection disruption to database; if the thread continues to show same pattern or remains stuck (use AWR reports to debug)
    @@ -501,7 +501,7 @@ xmlns="http://java.net/projects/threadlogic">
         WLS JMS Cluster has undergone some change - either change (add/drop) in cluster membership or change in consumers/producers. This can be seen during cluster start when members join the cluster. Can signify cluster instability or messaging. 
         Ensure cluster members or clients are not getting added/dropped too frequently after cluster has been up. Turn ON Cluster and JMS related debugs if there are repeat drop in clients
       
    -  
    +
       
         SOAP outbound calls from SOA
         NORMAL
    @@ -676,7 +676,7 @@ xmlns="http://java.net/projects/threadlogic">
         DeploymentServerService.start
         Deployment Service has been started
         Server bringing up deployment service. Deployments should complete in a finite time. Precompile application bits with the correct server version ahead of deployment if possible to speed up deployment time
    -    
    +  
       
         JSP Compilation
         NORMAL
    @@ -690,7 +690,7 @@ xmlns="http://java.net/projects/threadlogic">
         weblogic.jsp.internal.client.JobWaiter.blockUntilFinished
         JSP compilation job blocking request
         Thread waiting for jsp compilation to finish. Precompile application bits and JPSs against the correct server version ahead of deployment if possible
    -    
    +  
       
         WLS App undeployment
         WATCH
    @@ -775,7 +775,7 @@ xmlns="http://java.net/projects/threadlogic">
         Parallel GC Threads
         Large number of Parallel GC Threads used by JVM
         Reduce number of Parallel GC Threads, based on number of CPU/Cores and JVMs running on the host machine; Use -XXgcthreads:N for JRockit and -XX:ParallelGCThreads=N for HotSpot to limit number of parallel GC threads. Recommended # of GC Threads = (# of CPUs x # of Hardware Threads per core)/(# of JVMs on same machine). Example: Exalogic node 12 core, hyperthreaded means 24 hardware threads, and 2 JVMs imply 12 ParallelGC threads for each JVM
    -    
    +  
       
         Waiting for Event while blocking others
         WARNING
    @@ -824,7 +824,7 @@ xmlns="http://java.net/projects/threadlogic">
         com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.poll
         Poll for data/cache entry from remote Coherence members
         Normal
    -    
    +  
       
         Coherence waiting for EventQueue to drain
         WARNING
    @@ -866,7 +866,7 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.tip.adapter.aq.*AbstractDequeueAgent
         AQ Message dequeuing
         Normal AQ message dequeue thread
    -   
    +  
       
         AQ JMS Consumer
         NORMAL
    @@ -894,28 +894,28 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.tip.mediator.dispatch.db.DBContainerIdManager
         Oracle Mediator container id refresh wait
         Normal
    -    
    +  
       
         Oracle Mediator Locker
         NORMAL
         oracle.tip.mediator.common.listener.DBLocker
         Oracle Mediator locker thread locking the message for worker thread processing
         Normal
    -      
    +  
       
         Oracle SOA Cluster Node Heartbeat Locker
         NORMAL
         com.collaxa.cube.cluster.ClusterService
         Oracle SOA cluster node heartbeat service maintaining all cluster nodes heartbeat
         Normal
    -     
    +  
       
         Threaddump generation
         IGNORE
         racle.dfw.sampling.DumpSampling
         Threaddump generation
         Ignore
    -     
    +  
       
         Oracle SOA JMS Adapter
         NORMAL
    @@ -929,7 +929,7 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.tip.adapter.db.inbound,oracle.tip.adapter.db.InboundWork
         Oracle SOA DB Adapter running
         Normal
    -   
    +  
       
         Oracle Mediator waiting
         NORMAL
    @@ -943,7 +943,7 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.tip.mediator.service,oracle.tip.mediator.serviceEngine.MediatorServiceEngine
         Oracle Mediator Service running
         Normal
    -  	
    +  
       
         Oracle Mediator Resequencer
         WATCH
    @@ -957,35 +957,35 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.tip.resequencer.threadpool.WorkerThread
         Oracle Mediator resequencer worker thread
         Mediator resequencer under stress, please check the number of worker threads configured in EM and the target system log, this might be due to target system is slow
    -    
    +  
       
         Oracle Mediator Resequencer
         WATCH
         oracle.tip.mediator.resequencer.ResequencerDBLocker
         Oracle Mediator resequencer locker thread
         Mediator resequencer locker thread, there will be only 1 resequencer db locker thread to lock the group, if it is under stress or slow, please check the database performance
    -    
    +  
       
         Oracle Mediator Resequencer
         WATCH
         oracle.tip.resequencer.threadpool.ResequencerDBLocker, oracle.tip.resequencer.threadpool.AbstractLocker
         Oracle Mediator resequencer locker thread
         Mediator resequencer locker thread, there will be only 1 resequencer db locker thread to lock the group, if it is under stress or slow, please check the database performance
    -      
    +  
       
         Oracle Mediator Resequencer
         NORMAL
         oracle.tip.resequencer
         Oracle Mediator resequencer thread
         Ignore
    -       
    +  
       
         WLS Persistent Store Thread
         NORMAL
         weblogic.store.internal.PersistentStoreImpl.getOutstandingWork
         Thread handling WLS Persistent Store
         Normal thread handling wls file based persistence
    -    
    +  
       
         WLS StoreIO Writes
         NORMAL
    @@ -1000,7 +1000,7 @@ xmlns="http://java.net/projects/threadlogic">
         WLS starting recovery of persistent stores (JMS filestores or default stores) at startup
         The recovery will affect server startup based on number of messasges in the jms stores; compact JMS file stores if possible before restart; Refer to JMS Documentation on weblogic.store.Admin utility
       
    -  
    +
       
         WLS NM Client
         NORMAL
    @@ -1035,8 +1035,8 @@ xmlns="http://java.net/projects/threadlogic">
         WriteLock.lock
         Thread attempting to acquire java concurrent Write Lock
         
    -      Treat it as blocked thread; Check if the thread continues in Parked state or acquired the lock; 
    -    Use -XX:+PrintConcurrentLocks to print the details of locks; Enable jvm flag -XX:+UseMembar if threads are blocked for Reentrant locks with OSB   
    +      Treat it as blocked thread; Check if the thread continues in Parked state or acquired the lock;
    +    Use -XX:+PrintConcurrentLocks to print the details of locks; Enable jvm flag -XX:+UseMembar if threads are blocked for Reentrant locks with OSB
         
       
       
    @@ -1210,7 +1210,7 @@ xmlns="http://java.net/projects/threadlogic">
       
         WLS Replicated Session Secondary
         NORMAL
    -    ReplicatedSessionData.update             
    +    ReplicatedSessionData.update
         WLS webapp is using replicated session (in clustered instance)
         Normal, HTTP Session is replicated on secondary
       
    @@ -1297,7 +1297,7 @@ xmlns="http://java.net/projects/threadlogic">
         com.sun.hss.domain.util.spawn.UNIXProcess.waitForProcessExit
         Thread waiting for death of spawned off process
         Normal
    -    
    +  
       
         Sun xVM Appliance Details
         NORMAL
    @@ -1337,7 +1337,7 @@ xmlns="http://java.net/projects/threadlogic">
         NIOMuxer Bug 13962335 
         WARNING
         
         NIOSocketMuxer.*MuxableSocketT3.connect
         Check if WLS NIOMuxer is blocked for long, attempting to read from an unreachable endpoint, which can lead to stuck thread and severe Server Hang situations
    @@ -1370,74 +1370,74 @@ xmlns="http://java.net/projects/threadlogic">
         com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.sendTSH.*MQSession.close
         Threads communicating with MQ Series might go into wait state for long periods on closure of connections possibly due to shared conversations in MQ 7; Disable shared conversations if threads appear to hang or stay in wait state for long.
         Set the Sharing Conversation property of the Server Connection Channel to zero on MQ Series. Refer to Oracle Support Note Doc ID 1511617.1 or IBM Documentation on Shared Conversations 
    -    
    +  
       
         ONS Event Wait
         NORMAL
    -    oracle.ons.NotificationQueue.dequeue		         
    +    oracle.ons.NotificationQueue.dequeue
         Thread waiting for ONS Event
         Normal ONS event thread with Gridlink 
    -    
    +  
       
         Cavisson SQL Dump
         WARNING
    -    com.cavisson.ndutils.NDSys.dumpSQL		         
    +    com.cavisson.ndutils.NDSys.dumpSQL
         Cavisson capturing SQL dump; can introduce bottleneck among threads and degrade perf
         Remove or disable Cavisson SQL dump instrumentation 
       
       
         BTM Instrumentation
         WATCH
    -    com.amberpoint.nanoagent		         
    +    com.amberpoint.nanoagent
         Heavy code instrumentation or dynamic discovery can introduce overhead, slowness or degrade perf under heavy loads
         Disable BTM Amberpoint code instrumentation on perf degrade or slowness
       
       
         UCP Pool Conn
         WATCH
    -    UCPRACModuleImpl.getConnection		         
    +    UCPRACModuleImpl.getConnection
         Trying to get jdbc connection from UCP Gridlink pool for RAC
         If multiple threads appear with this pattern, set to Seconds to Trust Idle connection to 10 or 15 seconds, enable Pinned-to-thread and apply Bug# 17038851
       
       
         OJDL Logging
         WATCH
    -    oracle.core.ojdl.logging.ODLLogger		         
    +    oracle.core.ojdl.logging.ODLLogger
         Verbose logging levels in OJDL can slow down threads
         If multiple threads appear in blocked state waiting for lock during OJDL logging, set the logging level to less verbose (ex: ERROR instead of INFO) 
       
       
         BPEL wait for Response
         NORMAL
    -    com.collaxa.cube.engine.delivery.DeliveryService.getResult		         
    +    com.collaxa.cube.engine.delivery.DeliveryService.getResult
         Waiting for service response
         If its a long invocation, try to use async model
       
       
         BPEL Execution
         NORMAL
    -    com.collaxa.cube.engine.ejb.impl.bpel.BPELDeliveryBean		         
    +    com.collaxa.cube.engine.ejb.impl.bpel.BPELDeliveryBean
         BPELDelivery Bean execution for sync processes
         Normal
       
       
         BPEL Outbound WS Invoke
         NORMAL
    -    com.collaxa.cube.ws.WSInvocationManager.invoke		         
    +    com.collaxa.cube.ws.WSInvocationManager.invoke
         BPEL Layer invoking external Web Service
         Normal
       
       
         Oracle DMS
         NORMAL
    -    oracle.dms		         
    +    oracle.dms
         Oracle DMS Thread
         Normal
       
       
         Apache TSCCM ConnectionPool blockage
         WARNING
    -    org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking		         
    +    org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking
         Apache limits number of concurrent outbound http clients to 2 for a given destination and overall to 20
         Modify Apache Tsccm code to allow higher number of connections
       
    @@ -1510,14 +1510,14 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.dfw
         Oracle Diagnostic Framework
         Ignore
    -    
    +  
       
         Oracle SOA Cache Store for Audit
         IGNORE
         com.collaxa.cube.persistence.dao.impl.coherence.cachestore.AuditCachestore
         Oracle SOA write behind thread for audit cache store using coherence
         Ignore
    -      
    +  
       
         Oracle SOA Cache Store for delievery Messages
         IGNORE
    @@ -1531,21 +1531,21 @@ xmlns="http://java.net/projects/threadlogic">
         com.collaxa.cube.persistence.dao.impl.coherence.cachestore.XmlDocumentCacheStore
         Oracle SOA write behind thread for xml document using coherence
         Ignore
    -            
    +  
       
         Oracle SOA Cache Store for invoke messages
         IGNORE
         com.collaxa.cube.persistence.dao.impl.coherence.cachestore.InvokeMessageCacheStore
         Oracle SOA write behind thread for invoke messages using coherence
         Ignore
    -   
    +  
       
         Oracle SOA Cache Store for delivery subscription
         IGNORE
         com.collaxa.cube.persistence.dao.impl.coherence.cachestore.DeliverySubscriptionCacheStore
         Oracle SOA write behind thread for delivery subscription using coherence
         Ignore
    -   
    +  
       
         Oracle SOA Cache Store for cube instance
         IGNORE
    @@ -1559,28 +1559,28 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.soa.tracking
         Oracle SOA Instance Tracking
         Normal
    -          
    +  
       
         Oracle AIA Session Pool
         IGNORE
         oracle.apps.aia.core.sessionpool
         Oracle AIA Session Pool Manager Thread
         Ignore
    -         
    +  
       
         Oracle Mediator
         IGNORE
         oracle.tip.mediator.common.listener.AbstractWorker
         Oracle Mediator worker thread running
         Ignore
    -     
    +  
       
         Oracle EDN
         IGNORE
         oracle.integration.platform.blocks.event.saq.SAQBusinessEventBus
         Oracle EDN-DB uses Oracle AQ DB as backing store
         Ignore
    -   
    +  
       
         Oracle EDN
         IGNORE
    @@ -1594,138 +1594,145 @@ xmlns="http://java.net/projects/threadlogic">
         oracle.integration.platform.blocks.event.jms2.EdnJmsConnectionFactory
         Oracle EDN uses WLS JMS as backing store
         Ignore
    -     
    +  
       
         Oracle EDN
         IGNORE
         oracle.integration.platform.blocks.event.jms2.EdnAqConnectionFactory
         Oracle EDN uses AQ JMS as backing store
         Ignore
    -                
    +  
       
         MDS
         IGNORE
         oracle.mds
         MDS Thread
         Ignore
    -     
    +  
       
         BPEL Execution
         NORMAL
    -    com.collaxa.cube.engine.ejb.impl.bpel.BPELEngineBean,com.collaxa.cube.engine.ejb.impl.bpel.BPELDispatcherBean		         
    +    com.collaxa.cube.engine.ejb.impl.bpel.BPELEngineBean,com.collaxa.cube.engine.ejb.impl.bpel.BPELDispatcherBean
         BPEL Engine execution
         Normal
    -    
    +  
       
         BPEL Engine Overloaded
         WARNING
    -    BPELEngineBlocked		         
    +    BPELEngineBlocked
         BPEL Engine overloaded
         Possible BPEL Engine overloaded or slow if you see the same thread blocked in subsequence thread dumps, please review the stack trace and server logs, and check the all timeout settings, number of threads and the target system is able to handle the load
    -    
    +  
       
         BPEL Audit Trail
         NORMAL
    -    com.collaxa.cube.engine.ejb.impl.bpel.BPELAuditTrailBean		         
    +    com.collaxa.cube.engine.ejb.impl.bpel.BPELAuditTrailBean
         For BPEL Audit Trail
         Normal
    -      
    +  
       
         Oracle SOA Coherence Adapter
         NORMAL
    -    oracle.tip.adapter.coherence		         
    +    oracle.tip.adapter.coherence
         Oracle SOA Cloud Adapter running
         Normal
    -    
    +  
       
         Oracle SOA FTP Adapter
         NORMAL
    -    oracle.tip.adapter.ftp		         
    +    oracle.tip.adapter.ftp
         Oracle SOA FTP Adapter running
         Normal
    -    
    +  
       
         Oracle SOA LDAP Adapter
         NORMAL
    -    oracle.tip.adapter.ldap		         
    +    oracle.tip.adapter.ldap
         Oracle SOA LDAP Adapter running
         Normal
    -    
    +  
       
         Oracle SOA MQ Adapter
         NORMAL
    -    oracle.tip.adapter.mq		         
    +    oracle.tip.adapter.mq
         Oracle SOA MQ Adapter running
         Normal
       
       
         Oracle SOA MSMQ Adapter
         NORMAL
    -    oracle.tip.adapter.msmq		         
    +    oracle.tip.adapter.msmq
         Oracle SOA MSMQ Adapter running
    -    Normal      
    -                
    +    Normal
    +  
       
         Oracle SOA Socket Adapter
         NORMAL
    -    oracle.tip.adapter.socket		         
    +    oracle.tip.adapter.socket
         Oracle SOA Socket Adapter running
         Normal
       
       
         Oracle SOA UMS Adapter
         NORMAL
    -    oracle.tip.adapter.ums		         
    +    oracle.tip.adapter.ums
         Oracle SOA UMS Adapter running
         Normal
    -   
    +  
       
         DVM and XRef
         NORMAL
    -    oracle.tip.dvm		         
    +    oracle.tip.dvm
         Oracle SOA DVM and XRef
         Normal
       
       
         HTTP Client Contention
         FATAL
    -    HTTP Client Contention		         
    +    HTTP Client Contention
         HTTP requests using HTTPClient may cause a Heap retention and in consequence an OutOfMemory
         Please reivew: SOA 11g: "STUCK" Threads due to Contention in the Classes HTTPClient/StreamDemultiplexor Result in Server Performance Issues (Doc ID 1564631.1)
    -                
    +  
       
         DMS Collector
         FATAL
    -    DMS Collector Stucked		         
    +    DMS Collector Stucked
         Related to the DMS metrics engine, and probably proportional to having a lot of active managed servers.
         If have a very high transactional throughput or disruption, then the JVM needs the headroom to process this in addition to the inherent DMS metrics load. Apply patch for Bug 16298679 - DMS METRIC SAMPLER HAS PERFORMANCE BOTTLENECK.  The patch has significantly improved behaviour,and with the memory increase and some other limited JRockit tuning, The admin server shuold be stable.
       
       
         BPEL XPATH Function
         FATAL
    -    BPELXPATHFUNCTIONRESOLVER Stucked		         
    +    BPELXPATHFUNCTIONRESOLVER Stucked
         The issue has been identified in Bug:11778352 and is caused by the HashMap.get method call not thread safe  in BPELXPATHFUNCTIONRESOLVER
         Apply Patch:13353142
    -   
    +  
       
         Cluster Deployment
         FATAL
    -    Cluster Deployment Stucked		         
    +    Cluster Deployment Stucked
         You are unable to deploy a SOA composite in a clustered environment.
         The problem is likely to be caused by incorrect Coherence configuration. Please refer to support note: 1437883.1 -
    -   
    +  
       
         Oracle MFT Idle Thread
         IGNORE
         Oracle MFT Idle Thread
         MFT Idle Thread
         Ignore
    -      
    +  
       
         Oracle MFT Thread
         NORMAL
         oracle.tip.mft
         MFT Thread running
         Normal
    -        
    -  
    \ No newline at end of file
    +  
    +  
    +    Idle Task Thread
    +    IGNORE
    +    java.util.concurrent.LinkedBlockingQueue.poll
    +    Idle Task Thread waiting for an event
    +    Ignore
    +  
    +  
    diff --git a/src/java/com/oracle/ateam/threadlogic/resources/NonWLSGroups.xml b/src/java/com/oracle/ateam/threadlogic/resources/NonWLSGroups.xml
    index e7ee62f..a8da85a 100644
    --- a/src/java/com/oracle/ateam/threadlogic/resources/NonWLSGroups.xml
    +++ b/src/java/com/oracle/ateam/threadlogic/resources/NonWLSGroups.xml
    @@ -44,7 +44,7 @@ Using individual pattern entries for easier read:
     			Code Optimization Thread
     			VM Thread
     		
    -	      
    +	
     
     Or using | as delimiter to provide a choice of patterns:
     	
    @@ -57,7 +57,7 @@ Or using | as delimiter to provide a choice of patterns:
     		
       
         Socket Read
    -      
    +  
     	
     
     # MatchLocation used to locate for a matching pattern against thread stack or thread name : only allowed values are stack or name
    @@ -90,10 +90,10 @@ Or using | as delimiter to provide a choice of patterns:
       
         DB Execute
         Socket Read
    -          
    +  
     
     
    -# In above sample, the Complex Group "Oracle AQ Adapter" uses 2 underlying simple groups. 
    +# In above sample, the Complex Group "Oracle AQ Adapter" uses 2 underlying simple groups.
     # All threads belong to the simple group referred by "Oracle AQ AdapterTemp" should be included while all threads matching the "Oracle SOA DFW" should be excluded.
     
     # Also both Simple and Complex Groups can exclude certain advisories - as in downgrade those advisories from overall thread health consideration
    @@ -102,7 +102,7 @@ Or using | as delimiter to provide a choice of patterns:
     
     -->
     
    -
       Non WLS Groups
       
    @@ -141,30 +141,40 @@ xmlns="http://java.net/projects/threadlogic">
         
       
       
    -    IWay Adapter
    +    Tomcat Task Threads
         true
         true
         stack
         
    -      com.ibi.adapters.util
    +      org.apache.tomcat.util.threads.TaskThread
         
       
       
    -    SAP Connector
    +    Tomcat NIO Threads
         true
         true
         stack
         
    -      com.sap.conn.jco
    +      org.apache.tomcat.util.net.NioBlockingSelector
    +      org.apache.tomcat.util.net.NioEndpoint
         
       
       
    -    Other Poller
    +    IWay Adapter
         true
         true
         stack
         
    -      SelectorImpl.select
    +      com.ibi.adapters.util
    +    
    +  
    +  
    +    SAP Connector
    +    true
    +    true
    +    stack
    +    
    +      com.sap.conn.jco
         
       
       
    @@ -177,8 +187,8 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -               
    -    
    +    
    +  
       
         LDAP
         true
    @@ -190,7 +200,7 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -        
    +    
       
       
         RMI TCP Threads
    @@ -203,7 +213,7 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -        
    +    
       
       
         Java Timer
    @@ -232,10 +242,10 @@ xmlns="http://java.net/projects/threadlogic">
           oracle.repackaged.ons
           oracle.repackaged.ucp
         
    -    			
    +    
           Socket Read
         
    -    
    +  
       
         Quartz Pool
         true
    @@ -259,7 +269,7 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -         
    +    
       
       
         Wily
    @@ -276,8 +286,8 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -         
    -    
    +    
    +  
       
         EHCache
         true
    @@ -286,18 +296,18 @@ xmlns="http://java.net/projects/threadlogic">
         
           net.sf.ehcache.store.DiskStore
         
    -   
    +  
       
         Adventnet SNMP Agent
         true
         true
         stack
    -    			
    -      com.adventnet      
    +    
    +      com.adventnet
         
         
           Socket Read
    -         
    +    
       
       
         Sun Norm Updaters
    @@ -309,8 +319,8 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -         
    -    
    +    
    +  
       
         Sun HSS Grouping Manager Threads
         true
    @@ -318,7 +328,7 @@ xmlns="http://java.net/projects/threadlogic">
         name
         
           grouping-manager-attr-thread
    -        
    +    
       
       
         Sun JMX Client Notification Forwarders
    @@ -330,7 +340,7 @@ xmlns="http://java.net/projects/threadlogic">
         
         
           Socket Read
    -     
    +    
       
       
         ZK Web Framework Component Library
    @@ -339,8 +349,8 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           org.zkoss.zk
    -        
    -    
    +    
    +  
       
         Grizzly Threads
         true
    @@ -348,8 +358,8 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.sun.grizzly
    -        
    -   
    +    
    +  
       
         HK2 Transactions Notifiers
         true
    @@ -357,8 +367,8 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           org.jvnet.hk2.config.Transactions.Notifier
    -        
    -   
    +    
    +  
       
         Catalina Container Background Processors
         true
    @@ -366,34 +376,35 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           org.apache.catalina.core.ContainerBase.ContainerBackgroundProcessor
    -        
    -   
    +    
    +  
       
    -    JMX Client Heartbeat
    +    Datastax Threads
         true
         true
    -    name
    +    stack
         
    -      JMX client heartbeat
    -        
    -   
    +      com.datastax.shaded.netty.util.DefaultThreadFactory
    +      com.datastax.shaded.netty.util.concurrent.DefaultThreadFactory
    +    
    +  
       
    -    JMX Server Connection Timeout
    +    JMX Client Heartbeat
         true
         true
         name
         
    -      JMX server connection timeout
    -        
    +      JMX client heartbeat
    +    
       
       
    -    Log4J
    +    JMX Server Connection Timeout
         true
         true
         name
         
    -      Log4J 
    -        
    +      JMX server connection timeout
    +    
       
       
       
    @@ -413,7 +424,7 @@ xmlns="http://java.net/projects/threadlogic">
         name
         
           UCP-worker-thread
    -        
    +    
       
       
         Sun Cacao
    @@ -422,7 +433,7 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.sun.cacao
    -        
    +    
       
       
         Sun HSS Domain Temp
    @@ -432,7 +443,7 @@ xmlns="http://java.net/projects/threadlogic">
         
           com.sun.hss.domain
           com.sun.hss.services
    -        
    +    
       
       
         Sun HSS Domain
    @@ -445,8 +456,8 @@ xmlns="http://java.net/projects/threadlogic">
           Sun Norm Updaters
           Grizzly Threads
           Sun Cacao
    -            
    -    
    +    
    +  
       
         Iona CORBA
         true
    @@ -454,7 +465,7 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.iona
    -        
    +    
       
       
         Acsera
    @@ -463,7 +474,7 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.acsera.javaagent
    -        
    +    
       
       
         Cavisson
    @@ -472,7 +483,7 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.cavisson
    -        
    +    
       
       
         ODI
    @@ -482,7 +493,7 @@ xmlns="http://java.net/projects/threadlogic">
         
           oracle.odi
           com.sunopsis
    -        
    +    
       
       
         Stellent
    @@ -491,6 +502,33 @@ xmlns="http://java.net/projects/threadlogic">
         stack
         
           com.stellent.cis
    -        
    +    
    +  
    +  
    +    Apache Log4j
    +    true
    +    true
    +    stack
    +    
    +      org.apache.log4j
    +    
    +  
    +  
    +    Apache Logging
    +    true
    +    true
    +    stack
    +    
    +      org.apache.juli
    +    
    +  
    +  
    +    Other Poller
    +    true
    +    true
    +    stack
    +    
    +      SelectorImpl.select
    +