Created
November 1, 2016 15:16
-
-
Save andreybpanfilov/4db5340e25b1bea03e5615c44391ad80 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@page import="java.io.IOException" %> | |
<%@page import="java.io.PrintWriter" %> | |
<%@page import="java.lang.management.LockInfo" %> | |
<%@page import="java.lang.management.ManagementFactory" %> | |
<%@page import="java.lang.management.MonitorInfo" %> | |
<%@ page import="java.lang.management.ThreadInfo" %> | |
<%@ page import="java.lang.management.ThreadMXBean" %> | |
<%@ page import="java.util.ArrayList" %> | |
<%@ page import="java.util.Collections" %> | |
<%@ page import="java.util.List" %> | |
<%@ page import="com.documentum.web.common.LocaleService" %> | |
<%@ page import="com.documentum.web.formext.session.SessionManagerHttpBinding" %> | |
<%@ page contentType="text/html;charset=UTF-8" language="java" %> | |
<%! | |
public class MyThreadInfo implements Comparable<MyThreadInfo> { | |
private final long threadID; | |
private final ThreadInfo threadInfo; | |
private final String name; | |
public MyThreadInfo(ThreadInfo info) { | |
threadInfo = info; | |
name = info.getThreadName(); | |
threadID = info.getThreadId(); | |
} | |
public int compareTo(MyThreadInfo o) { | |
String myName = name + threadID; | |
String yourName = o.name + o.threadID; | |
return myName.compareTo(yourName); | |
} | |
} | |
public List<MyThreadInfo> getThreads(boolean deadlock) { | |
ThreadMXBean tmb = ManagementFactory.getThreadMXBean(); | |
ArrayList<MyThreadInfo> threads = new ArrayList<MyThreadInfo>(); | |
long[] threadIds = null; | |
if (deadlock) { | |
threadIds = tmb.findDeadlockedThreads(); | |
} else { | |
threadIds = tmb.getAllThreadIds(); | |
} | |
if (threadIds == null) { | |
return Collections.emptyList(); | |
} | |
for (ThreadInfo info : tmb.getThreadInfo(threadIds, true, true)) { | |
if (info != null) { | |
threads.add(new MyThreadInfo(info)); | |
} | |
} | |
Collections.sort(threads); | |
return threads; | |
} | |
public String toString(ThreadInfo threadInfo) { | |
StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" + | |
" Id=" + threadInfo.getThreadId() + " " + | |
threadInfo.getThreadState()); | |
if (threadInfo.getLockName() != null) { | |
sb.append(" on ").append(threadInfo.getLockName()); | |
} | |
if (threadInfo.getLockOwnerName() != null) { | |
sb.append(" owned by \"").append(threadInfo.getLockOwnerName()).append("\" Id=").append(threadInfo.getLockOwnerId()); | |
} | |
if (threadInfo.isSuspended()) { | |
sb.append(" (suspended)"); | |
} | |
if (threadInfo.isInNative()) { | |
sb.append(" (in native)"); | |
} | |
sb.append('\n'); | |
StackTraceElement[] stackTrace = threadInfo.getStackTrace(); | |
for (int i = 0, n = stackTrace.length; i < n; i++) { | |
StackTraceElement ste = stackTrace[i]; | |
sb.append("\tat ").append(ste.toString()); | |
sb.append('\n'); | |
if (i == 0 && threadInfo.getLockInfo() != null) { | |
Thread.State ts = threadInfo.getThreadState(); | |
switch (ts) { | |
case BLOCKED: | |
sb.append("\t- blocked on ").append(threadInfo.getLockInfo()); | |
sb.append('\n'); | |
break; | |
case WAITING: | |
sb.append("\t- waiting on ").append(threadInfo.getLockInfo()); | |
sb.append('\n'); | |
break; | |
case TIMED_WAITING: | |
sb.append("\t- waiting on ").append(threadInfo.getLockInfo()); | |
sb.append('\n'); | |
break; | |
default: | |
} | |
} | |
for (MonitorInfo mi : threadInfo.getLockedMonitors()) { | |
if (mi.getLockedStackDepth() == i) { | |
sb.append("\t- locked ").append(mi); | |
sb.append('\n'); | |
} | |
} | |
} | |
LockInfo[] locks = threadInfo.getLockedSynchronizers(); | |
if (locks.length > 0) { | |
sb.append("\n\tNumber of locked synchronizers = ").append(locks.length); | |
sb.append('\n'); | |
for (LockInfo li : locks) { | |
sb.append("\t- ").append(li); | |
sb.append('\n'); | |
} | |
} | |
sb.append('\n'); | |
return sb.toString(); | |
} | |
public void printThreads(List<MyThreadInfo> threads, JspWriter out) throws IOException { | |
out.println("<br><b>Total threads: " + threads.size() + "</b>"); | |
for (MyThreadInfo mti : threads) { | |
out.println("<pre>"); | |
out.print(toString(mti.threadInfo)); | |
out.println("</pre>"); | |
} | |
} | |
%> | |
<html> | |
<body> | |
<table> | |
<tr> | |
<td><b>Date:</b></td> | |
<td><%=new java.util.Date()%> | |
</td> | |
</tr> | |
<tr> | |
<td><b>User:</b></td> | |
<td><%=SessionManagerHttpBinding.getUsername()%> | |
</td> | |
</tr> | |
<tr> | |
<td><b>TimeZone:</b></td> | |
<td><%=LocaleService.getTimeZone()%> | |
</td> | |
</tr> | |
</table> | |
<% | |
try { | |
printThreads(getThreads(false), out); | |
List<MyThreadInfo> deadLockedThreads = getThreads(true); | |
if (deadLockedThreads != null && !deadLockedThreads.isEmpty()) { | |
out.print("<br><b>Found deadlocks:<b>"); | |
printThreads(deadLockedThreads, out); | |
} | |
} catch (Exception e) { | |
out.print("<pre>"); | |
e.printStackTrace(new PrintWriter(out, true)); | |
out.print("</pre>"); | |
} | |
%> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment