package org.zstack.utils; import org.zstack.utils.logging.CLogger; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** */ public class DebugUtils { public static class TimeStatistic { private long totalTime; private long count; private long averageTime; private String name; public long getTotalTime() { return totalTime; } public void setTotalTime(long totalTime) { this.totalTime = totalTime; } public long getCount() { return count; } public void setCount(long count) { this.count = count; } public long getAverageTime() { return averageTime; } public void setAverageTime(long averageTime) { this.averageTime = averageTime; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void addStatistic(long time) { totalTime += time; count ++; averageTime = totalTime / count; } @Override public String toString() { return String.format("Time statistic[%s]: total time: %s secs, total count: %s, average time: %s secs", name, TimeUnit.MILLISECONDS.toSeconds(totalTime), count, TimeUnit.MILLISECONDS.toSeconds(averageTime)); } } private static final CLogger logger = Utils.getLogger(DebugUtils.class); private static final Map<String, TimeStatistic> timeStatistics = new ConcurrentHashMap<String, TimeStatistic>(); public static String getStackTrace() { StackTraceElement[] statements = Thread.currentThread().getStackTrace(); StringBuilder sb = new StringBuilder(); for (StackTraceElement s : statements) { sb.append("\t" + s.toString() + "\n"); } return sb.toString(); } public static void dumpStackTrace(String msg) { String stack = String.format("%s:\n%s", msg, getStackTrace()); logger.debug(stack); } public static void dumpStackTrace() { logger.debug(getStackTrace()); } public static void Assert(boolean exp, String msg) { if (!exp) { throw new RuntimeException(msg); } } private static Throwable recursivelyGetRootCause(Throwable e) { if (e.getCause() != null) { return recursivelyGetRootCause(e.getCause()); } return e; } public static void countTimeStatistic(String name, long time) { TimeStatistic stat = timeStatistics.get(name); if (stat == null) { stat = new TimeStatistic(); stat.setName(name); timeStatistics.put(name, stat); } stat.addStatistic(time); } public static Map<String, TimeStatistic> getTimeStatistics() { return timeStatistics; } public static Throwable getRootCause(Throwable e) { return recursivelyGetRootCause(e); } public static void dumpAllThreads() { final StringBuilder dump = new StringBuilder(); final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); final ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100); for (ThreadInfo threadInfo : threadInfos) { dump.append('"'); dump.append(threadInfo.getThreadName()); dump.append("\" "); final Thread.State state = threadInfo.getThreadState(); dump.append("\n java.lang.Thread.State: "); dump.append(state); final StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); for (final StackTraceElement stackTraceElement : stackTraceElements) { dump.append("\n at "); dump.append(stackTraceElement); } dump.append("\n\n"); } logger.debug(dump.toString()); } }