feat: thread/stack add limit stacktrace lines by --stacktrace-max/-smax

pull/2782/head
qxo 1 year ago
parent 57d8b62589
commit c64ef9cabd

@ -25,6 +25,8 @@ public class ThreadModel extends ResultModel {
private Map<Thread.State, Integer> threadStateCount; private Map<Thread.State, Integer> threadStateCount;
private boolean all; private boolean all;
private int stacktraceMax;
public ThreadModel() { public ThreadModel() {
} }
@ -98,4 +100,19 @@ public class ThreadModel extends ResultModel {
public void setAll(boolean all) { public void setAll(boolean all) {
this.all = all; this.all = all;
} }
/**
* @return int return the stacktraceMax
*/
public int getStacktraceMax() {
return stacktraceMax;
}
/**
* @param stacktraceMax the stacktraceMax to set
*/
public void setStacktraceMax(int stacktraceMax) {
this.stacktraceMax = stacktraceMax;
}
} }

@ -57,6 +57,7 @@ public class ThreadCommand extends AnnotatedCommand {
private boolean lockedMonitors = false; private boolean lockedMonitors = false;
private boolean lockedSynchronizers = false; private boolean lockedSynchronizers = false;
private boolean all = false; private boolean all = false;
private int stacktraceMax;
static { static {
states = new HashSet<String>(State.values().length); states = new HashSet<String>(State.values().length);
@ -71,6 +72,12 @@ public class ThreadCommand extends AnnotatedCommand {
this.id = id; this.id = id;
} }
@Option(longName = "stacktrace-max", shortName = "smax")
@Description("limit stacktrace max number")
public void setStacktraceMax(int stacktraceMax) {
this.stacktraceMax = stacktraceMax;
}
@Option(longName = "all", flag = true) @Option(longName = "all", flag = true)
@Description("Display all thread results instead of the first page") @Description("Display all thread results instead of the first page")
public void setAll(boolean all) { public void setAll(boolean all) {
@ -168,7 +175,9 @@ public class ThreadCommand extends AnnotatedCommand {
threadSampler.pause(sampleInterval); threadSampler.pause(sampleInterval);
List<ThreadVO> threadStats = threadSampler.sample(resultThreads); List<ThreadVO> threadStats = threadSampler.sample(resultThreads);
process.appendResult(new ThreadModel(threadStats, stateCountMap, all)); final ThreadModel model = new ThreadModel(threadStats, stateCountMap, all);
model.setStacktraceMax(stacktraceMax);
process.appendResult(model);
return ExitStatus.success(); return ExitStatus.success();
} }
@ -177,7 +186,9 @@ public class ThreadCommand extends AnnotatedCommand {
if (blockingLockInfo.getThreadInfo() == null) { if (blockingLockInfo.getThreadInfo() == null) {
return ExitStatus.failure(1, "No most blocking thread found!"); return ExitStatus.failure(1, "No most blocking thread found!");
} }
process.appendResult(new ThreadModel(blockingLockInfo)); final ThreadModel model = new ThreadModel(blockingLockInfo);
model.setStacktraceMax(stacktraceMax);
process.appendResult(model);
return ExitStatus.success(); return ExitStatus.success();
} }
@ -215,7 +226,9 @@ public class ThreadCommand extends AnnotatedCommand {
BusyThreadInfo busyThread = new BusyThreadInfo(thread, threadInfo); BusyThreadInfo busyThread = new BusyThreadInfo(thread, threadInfo);
busyThreadInfos.add(busyThread); busyThreadInfos.add(busyThread);
} }
process.appendResult(new ThreadModel(busyThreadInfos)); final ThreadModel model = new ThreadModel(busyThreadInfos);
model.setStacktraceMax(stacktraceMax);
process.appendResult(model);
return ExitStatus.success(); return ExitStatus.success();
} }
@ -235,7 +248,9 @@ public class ThreadCommand extends AnnotatedCommand {
return ExitStatus.failure(1, "thread do not exist! id: " + id); return ExitStatus.failure(1, "thread do not exist! id: " + id);
} }
process.appendResult(new ThreadModel(threadInfos[0])); final ThreadModel model = new ThreadModel(threadInfos[0]);
model.setStacktraceMax(stacktraceMax);
process.appendResult(model);
return ExitStatus.success(); return ExitStatus.success();
} }
} }

@ -21,18 +21,19 @@ public class ThreadView extends ResultView<ThreadModel> {
@Override @Override
public void draw(CommandProcess process, ThreadModel result) { public void draw(CommandProcess process, ThreadModel result) {
final int stacktraceMax = result.getStacktraceMax();
if (result.getThreadInfo() != null) { if (result.getThreadInfo() != null) {
// no cpu usage info // no cpu usage info
String content = ThreadUtil.getFullStacktrace(result.getThreadInfo()); String content = ThreadUtil.getFullStacktrace(result.getThreadInfo(), stacktraceMax);
process.write(content); process.write(content);
} else if (result.getBusyThreads() != null) { } else if (result.getBusyThreads() != null) {
List<BusyThreadInfo> threadInfos = result.getBusyThreads(); List<BusyThreadInfo> threadInfos = result.getBusyThreads();
for (BusyThreadInfo info : threadInfos) { for (BusyThreadInfo info : threadInfos) {
String stacktrace = ThreadUtil.getFullStacktrace(info, -1, -1); String stacktrace = ThreadUtil.getFullStacktrace(info, -1, -1, stacktraceMax);
process.write(stacktrace).write("\n"); process.write(stacktrace).write("\n");
} }
} else if (result.getBlockingLockInfo() != null) { } else if (result.getBlockingLockInfo() != null) {
String stacktrace = ThreadUtil.getFullStacktrace(result.getBlockingLockInfo()); String stacktrace = ThreadUtil.getFullStacktrace(result.getBlockingLockInfo(), stacktraceMax);
process.write(stacktrace); process.write(stacktrace);
} else if (result.getThreadStateCount() != null) { } else if (result.getThreadStateCount() != null) {

@ -158,16 +158,23 @@ abstract public class ThreadUtil {
return blockingLockInfo; return blockingLockInfo;
} }
public static String getFullStacktrace(ThreadInfo threadInfo) { public static String getFullStacktrace(ThreadInfo threadInfo) {
return getFullStacktrace(threadInfo, -1, -1, -1, 0, 0); return getFullStacktrace(threadInfo, -1, -1, -1, 0, 0);
} }
public static String getFullStacktrace(final ThreadInfo threadInfo, final int stacktraceMax) {
return getFullStacktrace(threadInfo, -1, -1, -1, 0, 0, stacktraceMax);
}
public static String getFullStacktrace(BlockingLockInfo blockingLockInfo) { public static String getFullStacktrace(BlockingLockInfo blockingLockInfo) {
return getFullStacktrace(blockingLockInfo.getThreadInfo(), -1, -1, -1, blockingLockInfo.getLockIdentityHashCode(), return getFullStacktrace(blockingLockInfo.getThreadInfo(), -1, -1, -1, blockingLockInfo.getLockIdentityHashCode(),
blockingLockInfo.getBlockingThreadCount()); blockingLockInfo.getBlockingThreadCount());
} }
public static String getFullStacktrace(final BlockingLockInfo blockingLockInfo, final int stacktraceMax) {
return getFullStacktrace(blockingLockInfo.getThreadInfo(), -1, -1, -1, blockingLockInfo.getLockIdentityHashCode(),
blockingLockInfo.getBlockingThreadCount(), stacktraceMax);
}
/** /**
* ThreadInfo copy * ThreadInfo copy
@ -179,6 +186,11 @@ abstract public class ThreadUtil {
*/ */
public static String getFullStacktrace(ThreadInfo threadInfo, double cpuUsage, long deltaTime, long time, int lockIdentityHashCode, public static String getFullStacktrace(ThreadInfo threadInfo, double cpuUsage, long deltaTime, long time, int lockIdentityHashCode,
int blockingThreadCount) { int blockingThreadCount) {
return getFullStacktrace(threadInfo, cpuUsage, deltaTime, time, lockIdentityHashCode, blockingThreadCount, 0);
}
public static String getFullStacktrace(ThreadInfo threadInfo, double cpuUsage, long deltaTime, long time,
int lockIdentityHashCode, int blockingThreadCount, final int stacktraceMax) {
StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" + " Id=" StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" + " Id="
+ threadInfo.getThreadId()); + threadInfo.getThreadId());
@ -242,6 +254,9 @@ abstract public class ThreadUtil {
} }
} }
++i; ++i;
if (stacktraceMax > 0 && i >= stacktraceMax) {
break;
}
} }
if (i < threadInfo.getStackTrace().length) { if (i < threadInfo.getStackTrace().length) {
sb.append("\t..."); sb.append("\t...");
@ -265,7 +280,11 @@ abstract public class ThreadUtil {
return sb.toString().replace("\t", " "); return sb.toString().replace("\t", " ");
} }
public static String getFullStacktrace(BusyThreadInfo threadInfo, int lockIdentityHashCode, int blockingThreadCount) { public static String getFullStacktrace(BusyThreadInfo threadInfo, int lockIdentityHashCode, int blockingThreadCount) {
return getFullStacktrace(threadInfo, lockIdentityHashCode, blockingThreadCount, 0);
}
public static String getFullStacktrace(BusyThreadInfo threadInfo, int lockIdentityHashCode, int blockingThreadCount, int stacktraceMax) {
StringBuilder sb = new StringBuilder("\"" + threadInfo.getName() + "\""); StringBuilder sb = new StringBuilder("\"" + threadInfo.getName() + "\"");
if (threadInfo.getId() > 0) { if (threadInfo.getId() > 0) {
sb.append(" Id=").append(threadInfo.getId()); sb.append(" Id=").append(threadInfo.getId());
@ -338,6 +357,10 @@ abstract public class ThreadUtil {
sb.append('\n'); sb.append('\n');
} }
} }
if (stacktraceMax > 0 && i > stacktraceMax) {
break;
}
} }
if (i < threadInfo.getStackTrace().length) { if (i < threadInfo.getStackTrace().length) {
sb.append("\t..."); sb.append("\t...");

Loading…
Cancel
Save