Skip to content

Instantly share code, notes, and snippets.

@kelapure
Created September 29, 2015 03:57
Show Gist options
  • Save kelapure/f304a9784c03ae329f21 to your computer and use it in GitHub Desktop.
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
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