Transform commands of pkg basic1000 (#1274)

This commit is contained in:
gongdewei
2020-06-29 21:09:47 +08:00
committed by GitHub
parent 0d61c15855
commit 853e9b6007
43 changed files with 1051 additions and 222 deletions
@@ -91,10 +91,9 @@ public class CatCommand extends AnnotatedCommand {
}
//目前不支持过滤,限制http请求执行的文件大小
int maxSizeLimitOfHttp = 128 * 1024;
boolean isHttpApiRequest = !process.session().isTty();
if (isHttpApiRequest && sizeLimit > maxSizeLimitOfHttp) {
process.end(-1, "When executing commands with http, sizeLimit cannot be large than: " + maxSizeLimitOfHttp);
int maxSizeLimitOfNonTty = 128 * 1024;
if (!process.session().isTty() && sizeLimit > maxSizeLimitOfNonTty) {
process.end(-1, "When executing in non-tty session, sizeLimit cannot be large than: " + maxSizeLimitOfNonTty);
return false;
}
return true;
@@ -11,6 +11,10 @@ import com.taobao.text.util.RenderUtil;
public class ClsCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
if (!process.session().isTty()) {
process.end(-1, "Command 'cls' is only support tty session.");
return;
}
process.write(RenderUtil.cls()).write("\n");
process.end();
}
@@ -168,7 +168,6 @@ public class GrepCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write("The grep command only for pipes. See 'grep --help'\n");
process.end();
process.end(-1, "The grep command only for pipes. See 'grep --help'\n");
}
}
@@ -5,10 +5,10 @@ import java.util.List;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.HistoryModel;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.shell.history.HistoryManager;
import com.taobao.arthas.core.shell.history.impl.HistoryManagerImpl;
import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.shell.term.impl.TermImpl;
import com.taobao.middleware.cli.annotations.Argument;
@@ -47,6 +47,7 @@ public class HistoryCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
Session session = process.session();
//TODO 修改term history实现方式,统一使用HistoryManager
Object termObject = session.get(Session.TTY);
if (termObject != null && termObject instanceof TermImpl) {
TermImpl term = (TermImpl) termObject;
@@ -73,11 +74,12 @@ public class HistoryCommand extends AnnotatedCommand {
process.write(sb.toString());
}
} else {
//http api
HistoryManager historyManager = ArthasBootstrap.getInstance().getHistoryManager();
if (clear) {
HistoryManagerImpl.getInstance().clearHistory();
historyManager.clearHistory();
} else {
//http api
List<String> history = HistoryManagerImpl.getInstance().getHistory();
List<String> history = historyManager.getHistory();
process.appendResult(new HistoryModel(new ArrayList<String>(history)));
}
}
@@ -35,6 +35,11 @@ public class KeymapCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
if (!process.session().isTty()) {
process.end(-1, "Command 'keymap' is only support tty session.");
return;
}
InputStream inputrc = Helper.loadInputRcFile();
try {
TableElement table = new TableElement(1, 1, 2).leftCellPadding(1).rightCellPadding(1);
@@ -3,6 +3,10 @@ package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.GlobalOptions;
import com.taobao.arthas.core.Option;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.ChangeResultVO;
import com.taobao.arthas.core.command.model.OptionVO;
import com.taobao.arthas.core.command.model.OptionsModel;
import com.taobao.arthas.core.command.model.StatusModel;
import com.taobao.arthas.core.shell.cli.CliToken;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
@@ -18,10 +22,8 @@ import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
import com.taobao.text.ui.Element;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -29,7 +31,6 @@ import java.util.Collection;
import java.util.List;
import static com.taobao.arthas.core.util.ArthasCheckUtils.isIn;
import static com.taobao.text.ui.Element.label;
import static java.lang.String.format;
/**
@@ -48,6 +49,9 @@ import static java.lang.String.format;
Constants.WIKI + Constants.WIKI_HOME + "options")
//@formatter:on
public class OptionsCommand extends AnnotatedCommand {
private static final Logger logger = LoggerFactory.getLogger(OptionsCommand.class);
private String optionName;
private String optionValue;
@@ -66,17 +70,23 @@ public class OptionsCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
try {
StatusModel statusModel = null;
if (isShow()) {
processShow(process);
statusModel = processShow(process);
} else if (isShowName()) {
processShowName(process);
statusModel = processShowName(process);
} else {
processChangeNameValue(process);
statusModel = processChangeNameValue(process);
}
if (statusModel != null) {
process.end(statusModel.getStatusCode(), statusModel.getMessage());
} else {
process.end(-1, "command was not processed");
}
} catch (Throwable t) {
// ignore
} finally {
process.end();
logger.error("process options command error", t);
process.end(-1, "process options command error");
}
}
@@ -100,23 +110,24 @@ public class OptionsCommand extends AnnotatedCommand {
}
}
private void processShow(CommandProcess process) throws IllegalAccessException {
private StatusModel processShow(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new RegexMatcher(".*"));
process.write(RenderUtil.render(drawShowTable(fields), process.width()));
process.appendResult(new OptionsModel(convertToOptionVOs(fields)));
return StatusModel.success();
}
private void processShowName(CommandProcess process) throws IllegalAccessException {
private StatusModel processShowName(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new EqualsMatcher<String>(optionName));
process.write(RenderUtil.render(drawShowTable(fields), process.width()));
process.appendResult(new OptionsModel(convertToOptionVOs(fields)));
return StatusModel.success();
}
private void processChangeNameValue(CommandProcess process) throws IllegalAccessException {
private StatusModel processChangeNameValue(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new EqualsMatcher<String>(optionName));
// name not exists
if (fields.isEmpty()) {
process.write(format("options[%s] not found.\n", optionName));
return;
return StatusModel.failure(-1, format("options[%s] not found.", optionName));
}
Field field = fields.iterator().next();
@@ -144,22 +155,16 @@ public class OptionsCommand extends AnnotatedCommand {
} else if (isIn(type, short.class, String.class)) {
FieldUtils.writeStaticField(field, afterValue = optionValue);
} else {
process.write(format("Options[%s] type[%s] desupported.\n", optionName, type.getSimpleName()));
return;
return StatusModel.failure(-1, format("Options[%s] type[%s] was unsupported.", optionName, type.getSimpleName()));
}
} catch (Throwable t) {
process.write(format("Cannot cast option value[%s] to type[%s].\n", optionValue, type.getSimpleName()));
return;
return StatusModel.failure(-1, format("Cannot cast option value[%s] to type[%s].", optionValue, type.getSimpleName()));
}
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
table.row(true, label("NAME").style(Decoration.bold.bold()),
label("BEFORE-VALUE").style(Decoration.bold.bold()),
label("AFTER-VALUE").style(Decoration.bold.bold()));
table.row(optionAnnotation.name(), StringUtils.objectToString(beforeValue),
StringUtils.objectToString(afterValue));
process.write(RenderUtil.render(table, process.width()));
ChangeResultVO changeResultVO = new ChangeResultVO(optionAnnotation.name(), beforeValue, afterValue);
process.appendResult(new OptionsModel(changeResultVO));
return StatusModel.success();
}
@@ -207,25 +212,24 @@ public class OptionsCommand extends AnnotatedCommand {
return optionAnnotation != null && optionNameMatcher.matching(optionAnnotation.name());
}
private Element drawShowTable(Collection<Field> optionFields) throws IllegalAccessException {
TableElement table = new TableElement(1, 1, 2, 1, 3, 6)
.leftCellPadding(1).rightCellPadding(1);
table.row(true, label("LEVEL").style(Decoration.bold.bold()),
label("TYPE").style(Decoration.bold.bold()),
label("NAME").style(Decoration.bold.bold()),
label("VALUE").style(Decoration.bold.bold()),
label("SUMMARY").style(Decoration.bold.bold()),
label("DESCRIPTION").style(Decoration.bold.bold()));
for (final Field optionField : optionFields) {
final Option optionAnnotation = optionField.getAnnotation(Option.class);
table.row("" + optionAnnotation.level(),
optionField.getType().getSimpleName(),
optionAnnotation.name(),
"" + optionField.get(null),
optionAnnotation.summary(),
optionAnnotation.description());
private List<OptionVO> convertToOptionVOs(Collection<Field> fields) throws IllegalAccessException {
List<OptionVO> list = new ArrayList<OptionVO>();
for (Field field : fields) {
list.add(convertToOptionVO(field));
}
return table;
return list;
}
private OptionVO convertToOptionVO(Field optionField) throws IllegalAccessException {
Option optionAnnotation = optionField.getAnnotation(Option.class);
OptionVO optionVO = new OptionVO();
optionVO.setLevel(optionAnnotation.level());
optionVO.setName(optionAnnotation.name());
optionVO.setSummary(optionAnnotation.summary());
optionVO.setDescription(optionAnnotation.description());
optionVO.setType(optionField.getType().getSimpleName());
optionVO.setValue(""+optionField.get(null));
return optionVO;
}
}
@@ -2,6 +2,7 @@ package com.taobao.arthas.core.command.basic1000;
import java.io.File;
import com.taobao.arthas.core.command.model.PwdModel;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.middleware.cli.annotations.Name;
@@ -12,7 +13,8 @@ import com.taobao.middleware.cli.annotations.Summary;
public class PwdCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write(new File("").getAbsolutePath()).write("\n");
String path = new File("").getAbsolutePath();
process.appendResult(new PwdModel(path));
process.end();
}
}
@@ -2,6 +2,7 @@ package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.advisor.Enhancer;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.ResetModel;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.matcher.Matcher;
@@ -47,10 +48,9 @@ public class ResetCommand extends AnnotatedCommand {
public void process(CommandProcess process) {
Instrumentation inst = process.session().getInstrumentation();
Matcher matcher = SearchUtils.classNameMatcher(classPattern, isRegEx);
EnhancerAffect enhancerAffect = null;
try {
enhancerAffect = Enhancer.reset(inst, matcher);
process.write(enhancerAffect.toString()).write("\n");
EnhancerAffect enhancerAffect = Enhancer.reset(inst, matcher);
process.appendResult(new ResetModel(enhancerAffect));
} catch (UnmodifiableClassException e) {
// ignore
} finally {
@@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.command.model.SessionModel;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
@@ -7,12 +8,6 @@ import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.util.UserStatUtil;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
import com.taobao.text.ui.Element;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import static com.taobao.text.ui.Element.label;
import com.alibaba.arthas.tunnel.client.TunnelClient;
@@ -24,30 +19,30 @@ import com.alibaba.arthas.tunnel.client.TunnelClient;
@Name("session")
@Summary("Display current session information")
public class SessionCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write(RenderUtil.render(sessionTable(process.session()), process.width())).end();
}
SessionModel result = new SessionModel();
Session session = process.session();
result.setJavaPid(session.getPid());
result.setSessionId(session.getSessionId());
/*
* 会话详情
*/
private Element sessionTable(Session session) {
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
table.row(true, label("Name").style(Decoration.bold.bold()), label("Value").style(Decoration.bold.bold()));
table.row("JAVA_PID", "" + session.getPid()).row("SESSION_ID", "" + session.getSessionId());
//tunnel
TunnelClient tunnelClient = ArthasBootstrap.getInstance().getTunnelClient();
if (tunnelClient != null) {
String id = tunnelClient.getId();
if (id != null) {
table.row("AGENT_ID", "" + id);
result.setAgentId(id);
}
table.row("TUNNEL_SERVER", "" + tunnelClient.getTunnelServerUrl());
result.setTunnelServer(tunnelClient.getTunnelServerUrl());
}
//statUrl
String statUrl = UserStatUtil.getStatUrl();
if (statUrl != null) {
table.row("STAT_URL", statUrl);
}
return table;
result.setStatUrl(statUrl);
process.appendResult(result);
process.end();
}
}
@@ -1,6 +1,11 @@
package com.taobao.arthas.core.command.basic1000;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.core.advisor.Enhancer;
import com.taobao.arthas.core.command.model.MessageModel;
import com.taobao.arthas.core.command.model.ResetModel;
import com.taobao.arthas.core.command.model.ShutdownModel;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.ShellServer;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
@@ -13,7 +18,6 @@ import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
/**
* 关闭命令
@@ -25,6 +29,9 @@ import java.lang.instrument.UnmodifiableClassException;
@Summary("Shutdown Arthas server and exit the console")
@Hidden
public class ShutdownCommand extends AnnotatedCommand {
private static final Logger logger = LoggerFactory.getLogger(ShutdownCommand.class);
@Override
public void process(CommandProcess process) {
shutdown(process);
@@ -33,22 +40,32 @@ public class ShutdownCommand extends AnnotatedCommand {
public static void shutdown(CommandProcess process) {
try {
// 退出之前需要重置所有的增强类
process.appendResult(new MessageModel("Resetting all enhanced classes ..."));
Instrumentation inst = process.session().getInstrumentation();
EnhancerAffect enhancerAffect = Enhancer.reset(inst, new WildcardMatcher("*"));
process.write(enhancerAffect.toString()).write("\n");
process.write("Arthas Server is going to shut down...\n");
} catch (UnmodifiableClassException e) {
// ignore
process.appendResult(new ResetModel(enhancerAffect));
process.appendResult(new ShutdownModel(true, "Arthas Server is going to shut down..."));
} catch (Throwable e) {
logger.error("An error occurred when stopping arthas server.", e);
process.appendResult(new ShutdownModel(false, "An error occurred when stopping arthas server."));
} finally {
process.end();
ShellServer server = ArthasBootstrap.getInstance().getShellServer();
if (server != null) {
server.close();
try {
server.close();
} catch (Throwable e) {
logger.error("close shell server failure", e);
}
}
SessionManager sessionManager = ArthasBootstrap.getInstance().getSessionManager();
if (sessionManager != null){
sessionManager.close();
try {
sessionManager.close();
} catch (Throwable e) {
logger.error("close session manager failure", e);
}
}
}
}
@@ -1,11 +1,7 @@
package com.taobao.arthas.core.command.basic1000;
import static com.taobao.text.ui.Element.label;
import java.util.Map;
import java.util.Map.Entry;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.SystemEnvModel;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
@@ -15,9 +11,6 @@ import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
/**
* @author hengyunabc 2018-11-09
@@ -39,14 +32,18 @@ public class SystemEnvCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
try {
SystemEnvModel result = new SystemEnvModel();
if (StringUtils.isBlank(envName)) {
// show all system env
process.write(renderEnv(System.getenv(), process.width()));
result.putAll(System.getenv());
} else {
// view the specified system env
String value = System.getenv(envName);
process.write(envName + "=" + value + "\n");
result.put(envName, value);
}
process.appendResult(result);
} catch (Throwable t) {
process.end(-1, "Error during setting system env: " + t.getMessage());
} finally {
process.end();
}
@@ -64,14 +61,4 @@ public class SystemEnvCommand extends AnnotatedCommand {
CompletionUtils.complete(completion, System.getenv().keySet());
}
private String renderEnv(Map<String, String> envMap, int width) {
TableElement table = new TableElement(1, 4).leftCellPadding(1).rightCellPadding(1);
table.row(true, label("KEY").style(Decoration.bold.bold()), label("VALUE").style(Decoration.bold.bold()));
for (Entry<String, String> entry : envMap.entrySet()) {
table.row(entry.getKey(), entry.getValue());
}
return RenderUtil.render(table, width);
}
}
@@ -1,6 +1,9 @@
package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.MessageModel;
import com.taobao.arthas.core.command.model.StatusModel;
import com.taobao.arthas.core.command.model.SystemPropertyModel;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
@@ -10,13 +13,6 @@ import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import java.util.Properties;
import static com.taobao.text.ui.Element.label;
/**
* @author ralf0131 2017-01-09 14:03.
@@ -44,30 +40,30 @@ public class SystemPropertyCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
int status = 0;
try {
if (StringUtils.isBlank(propertyName) && StringUtils.isBlank(propertyValue)) {
// show all system properties
process.write(renderSystemProperties(System.getProperties(), process.width()));
process.appendResult(new SystemPropertyModel(System.getProperties()));
} else if (StringUtils.isBlank(propertyValue)) {
// view the specified system property
String value = System.getProperty(propertyName);
if (value == null) {
process.write("There is no property with the key " + propertyName + ".\n");
process.end(1, "There is no property with the key " + propertyName);
return;
} else {
process.write(propertyName + "=" + value + "\n");
process.appendResult(new SystemPropertyModel(propertyName, value));
}
} else {
// change system property
System.setProperty(propertyName, propertyValue);
process.write("Successfully changed the system property.\n");
process.write(propertyName + "=" + System.getProperty(propertyName) + "\n");
process.appendResult(new MessageModel("Successfully changed the system property."));
process.appendResult(new SystemPropertyModel(propertyName, System.getProperty(propertyName)));
}
} catch (Throwable t) {
process.write("Error during setting system property: " + t.getMessage() + "\n");
status = 1;
process.end(-1, "Error during setting system property: " + t.getMessage());
} finally {
process.end(status);
process.end();
}
}
@@ -80,16 +76,4 @@ public class SystemPropertyCommand extends AnnotatedCommand {
public void complete(Completion completion) {
CompletionUtils.complete(completion, System.getProperties().stringPropertyNames());
}
private String renderSystemProperties(Properties properties, int width) {
TableElement table = new TableElement(1, 4).leftCellPadding(1).rightCellPadding(1);
table.row(true, label("KEY").style(Decoration.bold.bold()),
label("VALUE").style(Decoration.bold.bold()));
for (String name: properties.stringPropertyNames()) {
table.row(name, properties.getProperty(name));
}
return RenderUtil.render(table, width);
}
}
@@ -34,8 +34,7 @@ public class TeeCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write("The tee command only for pipes. See 'tee --help'\n");
process.end();
process.end(-1, "The tee command only for pipes. See 'tee --help'");
}
public String getFilePath() {
@@ -1,7 +1,5 @@
package com.taobao.arthas.core.command.basic1000;
import static com.taobao.text.ui.Element.label;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
@@ -12,7 +10,9 @@ import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.express.OgnlExpress;
import com.taobao.arthas.core.command.model.ChangeResultVO;
import com.taobao.arthas.core.command.model.MessageModel;
import com.taobao.arthas.core.command.model.VMOptionModel;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
@@ -22,9 +22,6 @@ import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
/**
* vmoption command
@@ -66,41 +63,31 @@ public class VMOptionCommand extends AnnotatedCommand {
if (StringUtils.isBlank(name) && StringUtils.isBlank(value)) {
// show all options
process.write(renderVMOptions(hotSpotDiagnosticMXBean.getDiagnosticOptions(), process.width()));
process.appendResult(new VMOptionModel(hotSpotDiagnosticMXBean.getDiagnosticOptions()));
} else if (StringUtils.isBlank(value)) {
// view the specified option
VMOption option = hotSpotDiagnosticMXBean.getVMOption(name);
if (option == null) {
process.write("In order to change the system properties, you must specify the property value.\n");
process.end(-1, "In order to change the system properties, you must specify the property value.");
} else {
process.write(renderVMOptions(Arrays.asList(option), process.width()));
process.appendResult(new VMOptionModel(Arrays.asList(option)));
}
} else {
VMOption vmOption = hotSpotDiagnosticMXBean.getVMOption(name);
String originValue = vmOption.getValue();
// change vm option
hotSpotDiagnosticMXBean.setVMOption(name, value);
process.write("Successfully updated the vm option.\n");
process.write(name + "=" + hotSpotDiagnosticMXBean.getVMOption(name).getValue() + "\n");
process.appendResult(new MessageModel("Successfully updated the vm option."));
process.appendResult(new VMOptionModel(new ChangeResultVO(name, originValue,
hotSpotDiagnosticMXBean.getVMOption(name).getValue())));
}
} catch (Throwable t) {
process.write("Error during setting vm option: " + t.getMessage() + "\n");
logger.error("Error during setting vm option", t);
process.end(-1, "Error during setting vm option: " + t.getMessage());
} finally {
process.end();
}
}
private static String renderVMOptions(List<VMOption> diagnosticOptions, int width) {
TableElement table = new TableElement(1, 1, 1, 1).leftCellPadding(1).rightCellPadding(1);
table.row(true, label("KEY").style(Decoration.bold.bold()), label("VALUE").style(Decoration.bold.bold()),
label("ORIGIN").style(Decoration.bold.bold()),
label("WRITEABLE").style(Decoration.bold.bold()));
for (VMOption option : diagnosticOptions) {
table.row(option.getName(), option.getValue(), "" + option.getOrigin(), "" + option.isWriteable());
}
return RenderUtil.render(table, width);
}
@Override
@@ -0,0 +1,44 @@
package com.taobao.arthas.core.command.model;
/**
* @author gongdewei 2020/4/16
*/
public class ChangeResultVO {
private String name;
private Object beforeValue;
private Object afterValue;
public ChangeResultVO() {
}
public ChangeResultVO(String name, Object beforeValue, Object afterValue) {
this.name = name;
this.beforeValue = beforeValue;
this.afterValue = afterValue;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getBeforeValue() {
return beforeValue;
}
public void setBeforeValue(Object beforeValue) {
this.beforeValue = beforeValue;
}
public Object getAfterValue() {
return afterValue;
}
public void setAfterValue(Object afterValue) {
this.afterValue = afterValue;
}
}
@@ -0,0 +1,89 @@
package com.taobao.arthas.core.command.model;
import com.taobao.arthas.core.GlobalOptions;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author gongdewei 2020/6/22
*/
public class EnhancerAffectVO {
private final long cost;
private final int methodCount;
private final int classCount;
private final long listenerId;
private Throwable throwable;
private List<String> classDumpFiles;
private List<String> methods;
public EnhancerAffectVO(EnhancerAffect affect) {
this.cost = affect.cost();
this.classCount = affect.cCnt();
this.methodCount = affect.mCnt();
this.listenerId = affect.getListenerId();
this.throwable = affect.getThrowable();
if (GlobalOptions.isDump) {
classDumpFiles = new ArrayList<String>();
for (File classDumpFile : affect.getClassDumpFiles()) {
classDumpFiles.add(classDumpFile.getAbsolutePath());
}
}
if (GlobalOptions.verbose) {
methods = new ArrayList<String>();
methods.addAll(affect.getMethods());
}
}
public EnhancerAffectVO(long cost, int methodCount, int classCount, long listenerId) {
this.cost = cost;
this.methodCount = methodCount;
this.classCount = classCount;
this.listenerId = listenerId;
}
public long getCost() {
return cost;
}
public int getClassCount() {
return classCount;
}
public int getMethodCount() {
return methodCount;
}
public long getListenerId() {
return listenerId;
}
public Throwable getThrowable() {
return throwable;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
public List<String> getClassDumpFiles() {
return classDumpFiles;
}
public void setClassDumpFiles(List<String> classDumpFiles) {
this.classDumpFiles = classDumpFiles;
}
public List<String> getMethods() {
return methods;
}
public void setMethods(List<String> methods) {
this.methods = methods;
}
}
@@ -0,0 +1,61 @@
package com.taobao.arthas.core.command.model;
/**
* @author gongdewei 2020/4/15
*/
public class OptionVO {
private int level;
private String type;
private String name;
private String value;
private String summary;
private String description;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,43 @@
package com.taobao.arthas.core.command.model;
import java.util.List;
/**
* @author gongdewei 2020/4/15
*/
public class OptionsModel extends ResultModel{
private List<OptionVO> options;
private ChangeResultVO changeResult;
public OptionsModel() {
}
public OptionsModel(List<OptionVO> options) {
this.options = options;
}
public OptionsModel(ChangeResultVO changeResult) {
this.changeResult = changeResult;
}
@Override
public String getType() {
return "options";
}
public List<OptionVO> getOptions() {
return options;
}
public void setOptions(List<OptionVO> options) {
this.options = options;
}
public ChangeResultVO getChangeResult() {
return changeResult;
}
public void setChangeResult(ChangeResultVO changeResult) {
this.changeResult = changeResult;
}
}
@@ -0,0 +1,28 @@
package com.taobao.arthas.core.command.model;
/**
* @author gongdewei 2020/5/11
*/
public class PwdModel extends ResultModel {
private String workingDir;
public PwdModel() {
}
public PwdModel(String workingDir) {
this.workingDir = workingDir;
}
@Override
public String getType() {
return "pwd";
}
public String getWorkingDir() {
return workingDir;
}
public void setWorkingDir(String workingDir) {
this.workingDir = workingDir;
}
}
@@ -0,0 +1,33 @@
package com.taobao.arthas.core.command.model;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
/**
* @author gongdewei 2020/6/22
*/
public class ResetModel extends ResultModel {
private EnhancerAffectVO affect;
public ResetModel(EnhancerAffectVO affect) {
this.affect = affect;
}
public ResetModel(EnhancerAffect affect) {
this.affect = new EnhancerAffectVO(affect);
}
@Override
public String getType() {
return "reset";
}
public ResetModel affect(EnhancerAffect affect) {
this.affect = new EnhancerAffectVO(affect);
return this;
}
public EnhancerAffectVO getAffect() {
return affect;
}
}
@@ -0,0 +1,60 @@
package com.taobao.arthas.core.command.model;
/**
* Session command result model
*
* @author gongdewei 2020/03/27
*/
public class SessionModel extends ResultModel {
private long javaPid;
private String sessionId;
private String agentId;
private String tunnelServer;
private String statUrl;
@Override
public String getType() {
return "session";
}
public long getJavaPid() {
return javaPid;
}
public void setJavaPid(long javaPid) {
this.javaPid = javaPid;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public String getTunnelServer() {
return tunnelServer;
}
public void setTunnelServer(String tunnelServer) {
this.tunnelServer = tunnelServer;
}
public String getStatUrl() {
return statUrl;
}
public void setStatUrl(String statUrl) {
this.statUrl = statUrl;
}
}
@@ -0,0 +1,29 @@
package com.taobao.arthas.core.command.model;
/**
* @author gongdewei 2020/6/22
*/
public class ShutdownModel extends ResultModel {
private boolean graceful;
private String message;
public ShutdownModel(boolean graceful, String message) {
this.graceful = graceful;
this.message = message;
}
@Override
public String getType() {
return "shutdown";
}
public boolean isGraceful() {
return graceful;
}
public String getMessage() {
return message;
}
}
@@ -1,6 +1,17 @@
package com.taobao.arthas.core.command.model;
public class StatusModel extends ResultModel {
public static StatusModel success() {
return new StatusModel(0);
}
public static StatusModel failure(int statusCode, String message) {
if (statusCode == 0) {
throw new IllegalArgumentException("failure status code cannot be 0");
}
return new StatusModel(statusCode, message);
}
private int statusCode;
private String message;
@@ -0,0 +1,41 @@
package com.taobao.arthas.core.command.model;
import java.util.HashMap;
import java.util.Map;
/**
* sysenv KV Result
* @author gongdewei 2020/4/2
*/
public class SystemEnvModel extends ResultModel {
private Map<String, String> env = new HashMap<String, String>();
public SystemEnvModel() {
}
public SystemEnvModel(Map env) {
this.putAll(env);
}
public SystemEnvModel(String name, String value) {
this.put(name, value);
}
public Map<String, String> getEnv() {
return env;
}
public String put(String key, String value) {
return env.put(key, value);
}
public void putAll(Map m) {
env.putAll(m);
}
@Override
public String getType() {
return "sysenv";
}
}
@@ -0,0 +1,41 @@
package com.taobao.arthas.core.command.model;
import java.util.HashMap;
import java.util.Map;
/**
* Property KV Result
* @author gongdewei 2020/4/2
*/
public class SystemPropertyModel extends ResultModel {
private Map<String, String> props = new HashMap<String, String>();
public SystemPropertyModel() {
}
public SystemPropertyModel(Map props) {
this.putAll(props);
}
public SystemPropertyModel(String name, String value) {
this.put(name, value);
}
public Map<String, String> getProps() {
return props;
}
public String put(String key, String value) {
return props.put(key, value);
}
public void putAll(Map m) {
props.putAll(m);
}
@Override
public String getType() {
return "sysprop";
}
}
@@ -0,0 +1,47 @@
package com.taobao.arthas.core.command.model;
import com.sun.management.VMOption;
import java.util.List;
/**
* @author gongdewei 2020/4/15
*/
public class VMOptionModel extends ResultModel {
private List<VMOption> vmOptions;
private ChangeResultVO changeResult;
public VMOptionModel() {
}
public VMOptionModel(List<VMOption> vmOptions) {
this.vmOptions = vmOptions;
}
public VMOptionModel(ChangeResultVO changeResult) {
this.changeResult = changeResult;
}
@Override
public String getType() {
return "vmoption";
}
public List<VMOption> getVmOptions() {
return vmOptions;
}
public void setVmOptions(List<VMOption> vmOptions) {
this.vmOptions = vmOptions;
}
public ChangeResultVO getChangeResult() {
return changeResult;
}
public void setChangeResult(ChangeResultVO changeResult) {
this.changeResult = changeResult;
}
}
@@ -0,0 +1,50 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.OptionVO;
import com.taobao.arthas.core.command.model.OptionsModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.text.Decoration;
import com.taobao.text.ui.Element;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import java.util.Collection;
import static com.taobao.text.ui.Element.label;
/**
* @author gongdewei 2020/4/15
*/
public class OptionsView extends ResultView<OptionsModel> {
@Override
public void draw(CommandProcess process, OptionsModel result) {
if (result.getOptions() != null) {
process.write(RenderUtil.render(drawShowTable(result.getOptions()), process.width()));
} else if (result.getChangeResult() != null) {
TableElement table = ViewRenderUtil.renderChangeResult(result.getChangeResult());
process.write(RenderUtil.render(table, process.width()));
}
}
private Element drawShowTable(Collection<OptionVO> options) {
TableElement table = new TableElement(1, 1, 2, 1, 3, 6)
.leftCellPadding(1).rightCellPadding(1);
table.row(true, label("LEVEL").style(Decoration.bold.bold()),
label("TYPE").style(Decoration.bold.bold()),
label("NAME").style(Decoration.bold.bold()),
label("VALUE").style(Decoration.bold.bold()),
label("SUMMARY").style(Decoration.bold.bold()),
label("DESCRIPTION").style(Decoration.bold.bold()));
for (final OptionVO optionVO : options) {
table.row("" + optionVO.getLevel(),
optionVO.getType(),
optionVO.getName(),
optionVO.getValue(),
optionVO.getSummary(),
optionVO.getDescription());
}
return table;
}
}
@@ -0,0 +1,14 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.PwdModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
/**
* @author gongdewei 2020/5/11
*/
public class PwdView extends ResultView<PwdModel> {
@Override
public void draw(CommandProcess process, PwdModel result) {
process.write(result.getWorkingDir()).write("\n");
}
}
@@ -0,0 +1,16 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ResetModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
/**
* @author gongdewei 2020/6/22
*/
public class ResetView extends ResultView<ResetModel> {
@Override
public void draw(CommandProcess process, ResetModel result) {
process.write(ViewRenderUtil.renderEnhancerAffect(result.getAffect()));
}
}
@@ -2,7 +2,7 @@ package com.taobao.arthas.core.command.view;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.core.command.model.*;
import com.taobao.arthas.core.command.model.ResultModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import java.lang.reflect.Method;
@@ -20,23 +20,16 @@ public class ResultViewResolver {
// modelClass -> view
private Map<Class, ResultView> resultViewMap = new ConcurrentHashMap<Class, ResultView>();
private static ResultViewResolver viewResolver;
public static ResultViewResolver getInstance() {
if (viewResolver == null) {
synchronized (ResultViewResolver.class) {
viewResolver = new ResultViewResolver();
}
}
return viewResolver;
public ResultViewResolver() {
initResultViews();
}
static {
getInstance().registerResultViews();
}
private void registerResultViews() {
/**
* 需要调用此方法初始化注册ResultView
*/
private void initResultViews() {
try {
//basic1000
registerView(StatusView.class);
registerView(VersionView.class);
registerView(MessageView.class);
@@ -44,29 +37,42 @@ public class ResultViewResolver {
//registerView(HistoryView.class);
registerView(EchoView.class);
registerView(CatView.class);
registerView(OptionsView.class);
registerView(SystemPropertyView.class);
registerView(SystemEnvView.class);
registerView(PwdView.class);
registerView(VMOptionView.class);
registerView(SessionView.class);
registerView(ResetView.class);
registerView(ShutdownView.class);
//klass100
//logger
//monitor2000
} catch (Throwable e) {
logger.error("register result view failed", e);
}
}
private ResultViewResolver() {
}
public ResultView getResultView(ResultModel model) {
return resultViewMap.get(model.getClass());
}
public void registerView(Class modelClass, ResultView view) {
//TODO 检查model的type是否重复,减少复制代码带来的bug
public ResultViewResolver registerView(Class modelClass, ResultView view) {
//TODO 检查model的type是否重复,避免复制代码带来的bug
this.resultViewMap.put(modelClass, view);
return this;
}
public void registerView(ResultView view) {
public ResultViewResolver registerView(ResultView view) {
Class modelClass = getModelClass(view);
if (modelClass == null) {
throw new NullPointerException("model class is null");
}
this.registerView(modelClass, view);
return this.registerView(modelClass, view);
}
public void registerView(Class<? extends ResultView> viewClass) {
@@ -0,0 +1,36 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.SessionModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import static com.taobao.text.ui.Element.label;
/**
* Term / Tty view for session result
*
* @author gongdewei 2020/3/27
*/
public class SessionView extends ResultView<SessionModel> {
@Override
public void draw(CommandProcess process, SessionModel result) {
//会话详情
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
table.row(true, label("Name").style(Decoration.bold.bold()), label("Value").style(Decoration.bold.bold()));
table.row("JAVA_PID", "" + result.getJavaPid()).row("SESSION_ID", "" + result.getSessionId());
if (result.getAgentId() != null) {
table.row("AGENT_ID", "" + result.getAgentId());
}
if (result.getTunnelServer() != null) {
table.row("TUNNEL_SERVER", "" + result.getTunnelServer());
}
if (result.getStatUrl() != null) {
table.row("STAT_URL", result.getStatUrl());
}
process.write(RenderUtil.render(table, process.width()));
}
}
@@ -0,0 +1,14 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ShutdownModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
/**
* @author gongdewei 2020/6/22
*/
public class ShutdownView extends ResultView<ShutdownModel> {
@Override
public void draw(CommandProcess process, ShutdownModel result) {
process.write(result.getMessage()).write("\n");
}
}
@@ -0,0 +1,16 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.SystemEnvModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
/**
* @author gongdewei 2020/4/2
*/
public class SystemEnvView extends ResultView<SystemEnvModel> {
@Override
public void draw(CommandProcess process, SystemEnvModel result) {
process.write(ViewRenderUtil.renderKeyValueTable(result.getEnv(), process.width()));
}
}
@@ -0,0 +1,16 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.SystemPropertyModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
/**
* @author gongdewei 2020/4/2
*/
public class SystemPropertyView extends ResultView<SystemPropertyModel> {
@Override
public void draw(CommandProcess process, SystemPropertyModel result) {
process.write(ViewRenderUtil.renderKeyValueTable(result.getProps(), process.width()));
}
}
@@ -0,0 +1,42 @@
package com.taobao.arthas.core.command.view;
import com.sun.management.VMOption;
import com.taobao.arthas.core.command.model.VMOptionModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import java.util.List;
import static com.taobao.text.ui.Element.label;
/**
* @author gongdewei 2020/4/15
*/
public class VMOptionView extends ResultView<VMOptionModel> {
@Override
public void draw(CommandProcess process, VMOptionModel result) {
if (result.getVmOptions() != null) {
process.write(renderVMOptions(result.getVmOptions(), process.width()));
} else if (result.getChangeResult() != null) {
TableElement table = ViewRenderUtil.renderChangeResult(result.getChangeResult());
process.write(RenderUtil.render(table, process.width()));
}
}
private static String renderVMOptions(List<VMOption> diagnosticOptions, int width) {
TableElement table = new TableElement(1, 1, 1, 1).leftCellPadding(1).rightCellPadding(1);
table.row(true, label("KEY").style(Decoration.bold.bold()),
label("VALUE").style(Decoration.bold.bold()),
label("ORIGIN").style(Decoration.bold.bold()),
label("WRITEABLE").style(Decoration.bold.bold()));
for (VMOption option : diagnosticOptions) {
table.row(option.getName(), option.getValue(), "" + option.getOrigin(), "" + option.isWriteable());
}
return RenderUtil.render(table, width);
}
}
@@ -0,0 +1,88 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ChangeResultVO;
import com.taobao.arthas.core.command.model.EnhancerAffectVO;
import com.taobao.arthas.core.util.StringUtils;
import com.taobao.text.Decoration;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import java.util.List;
import java.util.Map;
import static com.taobao.text.ui.Element.label;
import static java.lang.String.format;
/**
* view render util for term/tty
* @author gongdewei 2020/6/22
*/
public class ViewRenderUtil {
/**
* Render key-value table
* @param map
* @param width
* @return
*/
public static String renderKeyValueTable(Map<String, String> map, int width) {
TableElement table = new TableElement(1, 4).leftCellPadding(1).rightCellPadding(1);
table.row(true, label("KEY").style(Decoration.bold.bold()), label("VALUE").style(Decoration.bold.bold()));
for (Map.Entry<String, String> entry : map.entrySet()) {
table.row(entry.getKey(), entry.getValue());
}
return RenderUtil.render(table, width);
}
/**
* Render change result vo
* @param result
* @return
*/
public static TableElement renderChangeResult(ChangeResultVO result) {
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
table.row(true, label("NAME").style(Decoration.bold.bold()),
label("BEFORE-VALUE").style(Decoration.bold.bold()),
label("AFTER-VALUE").style(Decoration.bold.bold()));
table.row(result.getName(), StringUtils.objectToString(result.getBeforeValue()),
StringUtils.objectToString(result.getAfterValue()));
return table;
}
/**
* Render EnhancerAffectVO
* @param affectVO
* @return
*/
public static String renderEnhancerAffect(EnhancerAffectVO affectVO) {
final StringBuilder infoSB = new StringBuilder();
List<String> classDumpFiles = affectVO.getClassDumpFiles();
if (classDumpFiles != null) {
for (String classDumpFile : classDumpFiles) {
infoSB.append("[dump: ").append(classDumpFile).append("]\n");
}
}
List<String> methods = affectVO.getMethods();
if (methods != null) {
for (String method : methods) {
infoSB.append("[Affect method: ").append(method).append("]\n");
}
}
infoSB.append(format("Affect(class count: %d , method count: %d) cost in %s ms, listenerId: %d",
affectVO.getClassCount(),
affectVO.getMethodCount(),
affectVO.getCost(),
affectVO.getListenerId()));
if (affectVO.getThrowable() != null) {
infoSB.append("\nEnhance error! exception: " + affectVO.getThrowable());
}
infoSB.append("\n");
return infoSB.toString();
}
}
@@ -16,9 +16,9 @@ public class TermResultDistributorImpl implements ResultDistributor {
private final CommandProcess commandProcess;
private final ResultViewResolver resultViewResolver;
public TermResultDistributorImpl(CommandProcess commandProcess) {
public TermResultDistributorImpl(CommandProcess commandProcess, ResultViewResolver resultViewResolver) {
this.commandProcess = commandProcess;
this.resultViewResolver = ResultViewResolver.getInstance();
this.resultViewResolver = resultViewResolver;
}
@Override
@@ -29,6 +29,7 @@ import com.taobao.arthas.common.AnsiLog;
import com.taobao.arthas.common.PidUtils;
import com.taobao.arthas.core.advisor.TransformerManager;
import com.taobao.arthas.core.command.BuiltinCommandPack;
import com.taobao.arthas.core.command.view.ResultViewResolver;
import com.taobao.arthas.core.config.BinderUtils;
import com.taobao.arthas.core.config.Configure;
import com.taobao.arthas.core.config.FeatureCodec;
@@ -40,10 +41,13 @@ import com.taobao.arthas.core.shell.ShellServer;
import com.taobao.arthas.core.shell.ShellServerOptions;
import com.taobao.arthas.core.shell.command.CommandResolver;
import com.taobao.arthas.core.shell.handlers.BindHandler;
import com.taobao.arthas.core.shell.history.HistoryManager;
import com.taobao.arthas.core.shell.history.impl.HistoryManagerImpl;
import com.taobao.arthas.core.shell.impl.ShellServerImpl;
import com.taobao.arthas.core.shell.session.SessionManager;
import com.taobao.arthas.core.shell.session.impl.SessionManagerImpl;
import com.taobao.arthas.core.shell.term.impl.HttpTermServer;
import com.taobao.arthas.core.shell.term.impl.http.api.HttpApiHandler;
import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer;
import com.taobao.arthas.core.util.ArthasBanner;
import com.taobao.arthas.core.util.FileUtils;
@@ -56,7 +60,6 @@ import io.netty.util.concurrent.EventExecutorGroup;
/**
* @author vlinux on 15/5/2.
* @author gongdewei 2020-03-25
*/
public class ArthasBootstrap {
private static final String ARTHAS_SPY_JAR = "arthas-spy.jar";
@@ -89,6 +92,12 @@ public class ArthasBootstrap {
private TransformerManager transformerManager;
private ResultViewResolver resultViewResolver;
private HistoryManager historyManager;
private HttpApiHandler httpApiHandler;
private ArthasBootstrap(Instrumentation instrumentation, Map<String, String> args) throws Throwable {
this.instrumentation = instrumentation;
@@ -103,7 +112,10 @@ public class ArthasBootstrap {
// 3. init logger
loggerContext = LogUtil.initLooger(arthasEnvironment);
// 4. start agent server
// 4. init beans
initBeans();
// 5. start agent server
bind(configure);
executorService = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@@ -127,6 +139,12 @@ public class ArthasBootstrap {
Runtime.getRuntime().addShutdownHook(shutdown);
}
private void initBeans() {
this.resultViewResolver = new ResultViewResolver();
this.historyManager = new HistoryManagerImpl();
}
private static void initSpy(Instrumentation instrumentation) throws Throwable {
// TODO init SpyImpl ?
@@ -320,6 +338,8 @@ public class ArthasBootstrap {
//http api session manager
sessionManager = new SessionManagerImpl(options, this, shellServer.getCommandManager(), shellServer.getJobController());
//http api handler
httpApiHandler = new HttpApiHandler(historyManager, sessionManager);
logger().info("as-server listening on network={};telnet={};http={};timeout={};", configure.getIp(),
configure.getTelnetPort(), configure.getHttpPort(), options.getConnectionTimeout());
@@ -495,4 +515,16 @@ public class ArthasBootstrap {
private Logger logger() {
return LoggerFactory.getLogger(this.getClass());
}
public ResultViewResolver getResultViewResolver() {
return resultViewResolver;
}
public HistoryManager getHistoryManager() {
return historyManager;
}
public HttpApiHandler getHttpApiHandler() {
return httpApiHandler;
}
}
@@ -19,18 +19,7 @@ public class HistoryManagerImpl implements HistoryManager {
private List<String> history = new ArrayList<String>();
private static HistoryManager instance;
public static HistoryManager getInstance() {
if (instance == null) {
synchronized (HistoryManagerImpl.class) {
instance = new HistoryManagerImpl();
}
}
return instance;
}
private HistoryManagerImpl() {
public HistoryManagerImpl() {
}
@Override
@@ -335,7 +335,7 @@ public class ProcessImpl implements Process {
process = new CommandProcessImpl(this, tty);
if (resultDistributor == null) {
resultDistributor = new TermResultDistributorImpl(process);
resultDistributor = new TermResultDistributorImpl(process, ArthasBootstrap.getInstance().getResultViewResolver());
}
final List<String> args2 = new LinkedList<String>();
@@ -9,6 +9,7 @@ import java.net.URL;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.common.IOUtils;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.term.impl.http.api.HttpApiHandler;
import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer;
@@ -49,7 +50,7 @@ public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequ
this.wsUri = wsUri;
this.dir = dir;
dir.mkdirs();
this.httpApiHandler = HttpApiHandler.getInstance();
this.httpApiHandler = ArthasBootstrap.getInstance().getHttpApiHandler();
}
@Override
@@ -10,13 +10,11 @@ import com.taobao.arthas.core.distribution.ResultConsumer;
import com.taobao.arthas.core.distribution.ResultDistributor;
import com.taobao.arthas.core.distribution.impl.PackingResultDistributorImpl;
import com.taobao.arthas.core.distribution.impl.ResultConsumerImpl;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.cli.CliToken;
import com.taobao.arthas.core.shell.cli.CliTokens;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.handlers.Handler;
import com.taobao.arthas.core.shell.history.HistoryManager;
import com.taobao.arthas.core.shell.history.impl.HistoryManagerImpl;
import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.shell.session.SessionManager;
import com.taobao.arthas.core.shell.system.Job;
@@ -67,20 +65,11 @@ public class HttpApiHandler {
private ArrayBlockingQueue<char[]> charsBufPool = new ArrayBlockingQueue<char[]>(poolSize);
private ArrayBlockingQueue<byte[]> bytesPool = new ArrayBlockingQueue<byte[]>(poolSize);
public static HttpApiHandler getInstance() {
if (instance == null) {
synchronized (HttpApiHandler.class) {
instance = new HttpApiHandler();
}
}
return instance;
}
private HttpApiHandler() {
sessionManager = ArthasBootstrap.getInstance().getSessionManager();
commandManager = sessionManager.getCommandManager();
jobController = sessionManager.getJobController();
historyManager = HistoryManagerImpl.getInstance();
public HttpApiHandler(HistoryManager historyManager, SessionManager sessionManager) {
this.historyManager = historyManager;
this.sessionManager = sessionManager;
commandManager = this.sessionManager.getCommandManager();
jobController = this.sessionManager.getJobController();
//init buf pool
JsonUtils.setSerializeWriterBufferThreshold(jsonBufferSize);
@@ -113,8 +113,17 @@ public final class EnhancerAffect extends Affect {
this.throwable = throwable;
}
public Collection<File> getClassDumpFiles() {
return classDumpFiles;
}
public List<String> getMethods() {
return methods;
}
@Override
public String toString() {
//TODO removing EnhancerAffect.toString(), replace with ViewRenderUtil.renderEnhancerAffect()
final StringBuilder infoSB = new StringBuilder();
if (GlobalOptions.isDump
&& !classDumpFiles.isEmpty()) {