Created
September 29, 2015 03:57
-
-
Save kelapure/f304a9784c03ae329f21 to your computer and use it in GitHub Desktop.
Servlet to Take a heapdump or thread dump to be incorporated into an application
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
package org.cloudfoundry.samples.music.debug; | |
import java.io.BufferedWriter; | |
import java.io.File; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.io.PrintWriter; | |
import java.io.Writer; | |
import java.lang.management.ManagementFactory; | |
import java.lang.management.ThreadInfo; | |
import java.lang.management.ThreadMXBean; | |
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
import java.util.HashMap; | |
import java.util.Map; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServlet; | |
import javax.servlet.http.HttpServletResponse; | |
import com.sun.management.HotSpotDiagnosticMXBean; | |
@SuppressWarnings("serial") | |
public class DumpServlet extends HttpServlet { | |
@Override | |
public void service(ServletRequest req, ServletResponse res) | |
throws ServletException, IOException { | |
PrintWriter out = ((HttpServletResponse) res).getWriter(); | |
out.println("Dumping... live"); | |
String type = req.getParameter("type"); | |
if (null != type) { | |
if (type.equals("heap")) { | |
File dumpFile = new File(System.currentTimeMillis()+ ".hprof"); | |
out.println("Dumping heap to " + dumpFile.getCanonicalPath()); | |
HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory | |
.getPlatformMXBeans(HotSpotDiagnosticMXBean.class).get(0); | |
hotSpotDiagnosticMXBean.dumpHeap(dumpFile.getAbsolutePath(),true); | |
} else if (type.equals("thread")) { | |
dumpStacks(out); | |
} | |
} | |
out.flush(); | |
out.close(); | |
} | |
public static void dumpStacks(PrintWriter out) throws IOException { | |
ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); | |
ThreadInfo[] threadInfos = mxBean.getThreadInfo( | |
mxBean.getAllThreadIds(), 0); | |
Map<Long, ThreadInfo> threadInfoMap = new HashMap<Long, ThreadInfo>(); | |
for (ThreadInfo threadInfo : threadInfos) { | |
threadInfoMap.put(threadInfo.getThreadId(), threadInfo); | |
} | |
// choose our dump-file | |
File dumpFile = new File("stacks." + System.currentTimeMillis()); | |
out.println("Dumping Thread Info to " + dumpFile.getCanonicalPath()); | |
Writer writer = new BufferedWriter(new FileWriter(dumpFile)); | |
try { | |
dumpTraces(mxBean, threadInfoMap, writer); | |
} finally { | |
writer.close(); | |
} | |
} | |
private static void dumpTraces(ThreadMXBean mxBean, | |
Map<Long, ThreadInfo> threadInfoMap, Writer writer) | |
throws IOException { | |
Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces(); | |
writer.write("Dump of " | |
+ stacks.size() | |
+ " thread at " | |
+ new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z") | |
.format(new Date(System.currentTimeMillis())) + "\n\n"); | |
for (Map.Entry<Thread, StackTraceElement[]> entry : stacks.entrySet()) { | |
Thread thread = entry.getKey(); | |
writer.write("\"" + thread.getName() + "\" prio=" | |
+ thread.getPriority() + " tid=" + thread.getId() + " " | |
+ thread.getState() + " " | |
+ (thread.isDaemon() ? "deamon" : "worker") + "\n"); | |
ThreadInfo threadInfo = threadInfoMap.get(thread.getId()); | |
if (threadInfo != null) { | |
writer.write(" native=" + threadInfo.isInNative() | |
+ ", suspended=" + threadInfo.isSuspended() | |
+ ", block=" + threadInfo.getBlockedCount() + ", wait=" | |
+ threadInfo.getWaitedCount() + "\n"); | |
writer.write(" lock=" | |
+ threadInfo.getLockName() | |
+ " owned by " | |
+ threadInfo.getLockOwnerName() | |
+ " (" | |
+ threadInfo.getLockOwnerId() | |
+ "), cpu=" | |
+ (mxBean.getThreadCpuTime(threadInfo.getThreadId()) / 1000000L) | |
+ ", user=" | |
+ (mxBean.getThreadUserTime(threadInfo.getThreadId()) / 1000000L) | |
+ "\n"); | |
} | |
for (StackTraceElement element : entry.getValue()) { | |
writer.write(" "); | |
writer.write(element.toString()); | |
writer.write("\n"); | |
} | |
writer.write("\n"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment