提交 b0e58528 编写于 作者: Z zhourui

增加定时thread dump 更新ThreadDump,HeapDump

上级 65c0b45f
......@@ -304,6 +304,11 @@ public class Config {
return SystemUtils.IS_OS_WINDOWS ? dir.resolve("bin/jstack.exe") : dir.resolve("bin/jstack");
}
public static Path command_jmap_path() {
Path dir = Paths.get(System.getProperty("java.home"));
return SystemUtils.IS_OS_WINDOWS ? dir.resolve("bin/jmap.exe") : dir.resolve("bin/jmap");
}
public static File dir_local() throws Exception {
return new File(base(), DIR_LOCAL);
}
......
......@@ -32,7 +32,7 @@ public class StackTraceTask implements Job {
String pid = Files.readString(Paths.get(Config.base(), "pid.log"));
String file = Config.dir_logs().getAbsolutePath() + "/jstack_" + Config.node() + "_"
+ DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".txt";
String command = Config.command_jstack_path().toString() + " -l " + pid + " > " + file;
String command = Config.command_jstack_path().toString() + " -l -e " + pid + " > " + file;
ProcessBuilder processBuilder = new ProcessBuilder();
if (SystemUtils.IS_OS_WINDOWS) {
processBuilder.command("cmd", "/c", command);
......
......@@ -151,8 +151,7 @@ public class ActionControl extends ActionBase {
}
private static Option tdOption() {
return Option.builder(CMD_TD).longOpt("threadDump").argName("count").optionalArg(true).hasArg()
.desc("服务器线程状态,间隔2秒.合并多次执行线程信息到最后一份日志.").build();
return Option.builder(CMD_TD).longOpt("threadDump").hasArg(false).desc("生成线程转储文件.").build();
}
private static Option ecOption() {
......@@ -243,9 +242,8 @@ public class ActionControl extends ActionBase {
}
private void td(CommandLine cmd) {
Integer count = this.getArgInteger(cmd, CMD_TD, 10);
ThreadDump threadDump = new ThreadDump();
threadDump.execute(count);
threadDump.execute();
}
private void clh2(CommandLine cmd) throws Exception {
......
package com.x.server.console.action;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import javax.management.MBeanServer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.DateTools;
import com.x.base.core.project.tools.DefaultCharset;
public class HeapDump {
private static Logger logger = LoggerFactory.getLogger(HeapDump.class);
private static final Logger LOGGER = LoggerFactory.getLogger(HeapDump.class);
private static final String HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic";
public void execute() throws Exception {
public void execute() {
try {
Date start = new Date();
File file = new File(Config.dir_logs(),
"heapDump_" + DateTools.format(start, DateTools.formatCompact_yyyyMMddHHmmss) + ".hprof");
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(server, HOTSPOT_BEAN_NAME,
HotSpotDiagnosticMXBean.class);
bean.dumpHeap(file.getAbsolutePath(), true);
logger.print(
"generate java heap dump to {}, elapsed: {}ms, parses file see url: https://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html",
file.getAbsoluteFile(), System.currentTimeMillis() - start.getTime());
Date now = new Date();
String pid = Files.readString(Paths.get(Config.base(), "pid.log"));
String file = Config.dir_logs().getAbsolutePath() + "/jmap_" + Config.node() + "_"
+ DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".hprof";
String command = Config.command_jmap_path().toString() + " -dump:format=b,file=" + file + " " + pid;
ProcessBuilder processBuilder = new ProcessBuilder();
if (SystemUtils.IS_OS_WINDOWS) {
processBuilder.command("cmd", "/c", command);
} else {
processBuilder.command("sh", "-c", command);
}
Process p = processBuilder.start();
String resp = IOUtils.toString(p.getErrorStream(), DefaultCharset.charset_utf_8);
LOGGER.print("heap dump to {}.{}", file, resp);
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
......
package com.x.server.console.action;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.DateTools;
import com.x.base.core.project.tools.DefaultCharset;
/**
*
......@@ -24,45 +20,27 @@ import com.x.base.core.project.tools.DateTools;
*/
public class ThreadDump {
private static Logger logger = LoggerFactory.getLogger(ThreadDump.class);
public void execute(Integer count) {
ExecutorService service = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
new BasicThreadFactory.Builder().namingPattern(ThreadDump.class.getName()).daemon(true).build());
service.execute(() -> {
try {
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
String jvmName = runtimeBean.getName();
long pid = Long.parseLong(jvmName.split("@")[0]);
Path path = SystemUtils.getJavaHome().toPath();
if (null != path) {
path = path.getParent().resolve("bin/jcmd").toAbsolutePath();
for (int i = 0; i < count; i++) {
Path out = Config.dir_logs(true).toPath()
.resolve("jcmd_Thread.print_" + pid + "_"
+ DateTools.format(new Date(), DateTools.formatCompact_yyyyMMddHHmmss) + ".txt")
.toAbsolutePath();
String cmd = path.toString() + " " + pid + " Thread.print >" + out.toString();
ProcessBuilder processBuilder = new ProcessBuilder();
if (SystemUtils.IS_OS_WINDOWS) {
processBuilder.command("cmd", "/c", cmd);
} else {
processBuilder.command("sh", "-c", cmd);
}
processBuilder.start();
logger.print("thread dump to file:{}.", out.toString());
Thread.sleep(1000);
}
logger.print("{} thread dump completed.", count);
}
} catch (InterruptedException e) {
logger.error(e);
Thread.currentThread().interrupt();
} catch (Exception e) {
logger.error(e);
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadDump.class);
public void execute() {
try {
Date now = new Date();
String pid = Files.readString(Paths.get(Config.base(), "pid.log"));
String file = Config.dir_logs().getAbsolutePath() + "/jstack_" + Config.node() + "_"
+ DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".txt";
String command = Config.command_jstack_path().toString() + " -l -e " + pid + " > " + file;
ProcessBuilder processBuilder = new ProcessBuilder();
if (SystemUtils.IS_OS_WINDOWS) {
processBuilder.command("cmd", "/c", command);
} else {
processBuilder.command("sh", "-c", command);
}
});
Process p = processBuilder.start();
String resp = IOUtils.toString(p.getErrorStream(), DefaultCharset.charset_utf_8);
LOGGER.print("thread dump to {}.{}", file, resp);
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册