Add off-by-default feature to automatically thread dump every 60 seconds

This commit is contained in:
embeddedt 2023-05-26 11:55:57 -04:00
parent 74eb8a0619
commit b5d62b4bbb
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
3 changed files with 37 additions and 18 deletions

View File

@ -11,6 +11,7 @@ import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
import org.embeddedt.modernfix.resources.ReloadExecutor;
import org.embeddedt.modernfix.util.ClassInfoManager;
import org.embeddedt.modernfix.world.IntegratedWatchdog;
import java.lang.management.ManagementFactory;
import java.util.concurrent.Executor;
@ -46,6 +47,19 @@ public class ModernFix {
public ModernFix() {
INSTANCE = this;
ModernFixPlatformHooks.onServerCommandRegister(ModernFixCommands::register);
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spam_thread_dump.ThreadDumper")) {
Thread t = new Thread() {
public void run() {
while(true) {
LOGGER.error("------ DEBUG THREAD DUMP (occurs every 60 seconds) ------");
LOGGER.error(IntegratedWatchdog.obtainThreadDump());
try { Thread.sleep(60000); } catch(InterruptedException e) {}
}
}
};
t.setDaemon(true);
t.start();
}
}
public void onServerStarted() {

View File

@ -147,6 +147,7 @@ public class ModernFixEarlyConfig {
.put("mixin.perf.deduplicate_location", false)
.put("mixin.feature.integrated_server_watchdog", true)
.put("mixin.perf.faster_item_rendering", false)
.put("mixin.feature.spam_thread_dump", false)
.put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees)
.put("mixin.devenv", isDevEnv)
.put("mixin.perf.remove_spawn_chunks", isDevEnv)

View File

@ -25,6 +25,27 @@ public class IntegratedWatchdog extends Thread {
this.setName("ModernFix integrated server watchdog");
}
public static String obtainThreadDump() {
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
sb.append("Thread Dump:\n");
for(ThreadInfo threadinfo : athreadinfo) {
sb.append(threadinfo);
StackTraceElement[] elements = threadinfo.getStackTrace();
if(elements.length > 8) {
sb.append("extended trace:\n");
for(int i = 8; i < elements.length; i++) {
sb.append("\tat ");
sb.append(elements[i]);
sb.append('\n');
}
}
sb.append('\n');
}
return sb.toString();
}
public void run() {
while(true) {
MinecraftServer server = this.server.get();
@ -35,24 +56,7 @@ public class IntegratedWatchdog extends Thread {
long delta = curTime - nextTick;
if(delta > MAX_TICK_DELTA) {
LOGGER.error("A single server tick has taken {}, more than {} milliseconds", delta, MAX_TICK_DELTA);
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
sb.append("Thread Dump:\n");
for(ThreadInfo threadinfo : athreadinfo) {
sb.append(threadinfo);
StackTraceElement[] elements = threadinfo.getStackTrace();
if(elements.length > 8) {
sb.append("extended trace:\n");
for(int i = 8; i < elements.length; i++) {
sb.append("\tat ");
sb.append(elements[i]);
sb.append('\n');
}
}
sb.append('\n');
}
LOGGER.error(sb);
LOGGER.error(obtainThreadDump());
nextTick = 0;
curTime = 0;
}