Commit 5d7c4150 authored by shengnan hu's avatar shengnan hu
Browse files

init

parents
Pipeline #4715 failed with stage
in 30 seconds
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.shell.cli.CliToken;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.shell.command.ExitStatus;
import com.taobao.arthas.core.util.CommandUtils;
import com.taobao.arthas.core.util.StringUtils;
import com.taobao.arthas.core.util.TokenUtils;
import com.taobao.arthas.core.util.matcher.EqualsMatcher;
import com.taobao.arthas.core.util.matcher.Matcher;
import com.taobao.arthas.core.util.matcher.RegexMatcher;
import com.taobao.arthas.core.util.reflect.FieldUtils;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.taobao.arthas.core.util.ArthasCheckUtils.isIn;
import static java.lang.String.format;
/**
* 选项开关命令
*
* @author vlinux on 15/6/6.
*/
// @formatter:off
@Name("options")
@Summary("View and change various Arthas options")
@Description(Constants.EXAMPLE +
"options # list all options\n" +
"options json-format true\n" +
"options dump true\n" +
"options unsafe true\n" +
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;
@Argument(index = 0, argName = "options-name", required = false)
@Description("Option name")
public void setOptionName(String optionName) {
this.optionName = optionName;
}
@Argument(index = 1, argName = "options-value", required = false)
@Description("Option value")
public void setOptionValue(String optionValue) {
this.optionValue = optionValue;
}
@Override
public void process(CommandProcess process) {
try {
ExitStatus status = null;
if (isShow()) {
status = processShow(process);
} else if (isShowName()) {
status = processShowName(process);
} else {
status = processChangeNameValue(process);
}
CommandUtils.end(process, status);
} catch (Throwable t) {
logger.error("processing error", t);
process.end(-1, "processing error");
}
}
/**
* complete first argument(options-name), other case use default complete
*
* @param completion the completion object
*/
@Override
public void complete(Completion completion) {
int argumentIndex = CompletionUtils.detectArgumentIndex(completion);
List<CliToken> lineTokens = completion.lineTokens();
if (argumentIndex == 1) {
String laseToken = TokenUtils.getLast(lineTokens).value().trim();
//prefix match options-name
String pattern = "^" + laseToken + ".*";
Collection<String> optionNames = findOptionNames(new RegexMatcher(pattern));
CompletionUtils.complete(completion, optionNames);
} else {
super.complete(completion);
}
}
private ExitStatus processShow(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new RegexMatcher(".*"));
process.appendResult(new OptionsModel(convertToOptionVOs(fields)));
return ExitStatus.success();
}
private ExitStatus processShowName(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new EqualsMatcher<String>(optionName));
process.appendResult(new OptionsModel(convertToOptionVOs(fields)));
return ExitStatus.success();
}
private ExitStatus processChangeNameValue(CommandProcess process) throws IllegalAccessException {
Collection<Field> fields = findOptionFields(new EqualsMatcher<String>(optionName));
// name not exists
if (fields.isEmpty()) {
return ExitStatus.failure(-1, format("options[%s] not found.", optionName));
}
Field field = fields.iterator().next();
Option optionAnnotation = field.getAnnotation(Option.class);
Class<?> type = field.getType();
Object beforeValue = FieldUtils.readStaticField(field);
Object afterValue;
try {
// try to case string to type
if (isIn(type, int.class, Integer.class)) {
FieldUtils.writeStaticField(field, afterValue = Integer.valueOf(optionValue));
} else if (isIn(type, long.class, Long.class)) {
FieldUtils.writeStaticField(field, afterValue = Long.valueOf(optionValue));
} else if (isIn(type, boolean.class, Boolean.class)) {
FieldUtils.writeStaticField(field, afterValue = Boolean.valueOf(optionValue));
} else if (isIn(type, double.class, Double.class)) {
FieldUtils.writeStaticField(field, afterValue = Double.valueOf(optionValue));
} else if (isIn(type, float.class, Float.class)) {
FieldUtils.writeStaticField(field, afterValue = Float.valueOf(optionValue));
} else if (isIn(type, byte.class, Byte.class)) {
FieldUtils.writeStaticField(field, afterValue = Byte.valueOf(optionValue));
} else if (isIn(type, short.class, Short.class)) {
FieldUtils.writeStaticField(field, afterValue = Short.valueOf(optionValue));
} else if (isIn(type, short.class, String.class)) {
FieldUtils.writeStaticField(field, afterValue = optionValue);
} else {
return ExitStatus.failure(-1, format("Options[%s] type[%s] was unsupported.", optionName, type.getSimpleName()));
}
} catch (Throwable t) {
return ExitStatus.failure(-1, format("Cannot cast option value[%s] to type[%s].", optionValue, type.getSimpleName()));
}
ChangeResultVO changeResultVO = new ChangeResultVO(optionAnnotation.name(), beforeValue, afterValue);
process.appendResult(new OptionsModel(changeResultVO));
return ExitStatus.success();
}
/**
* 判断当前动作是否需要展示整个options
*/
private boolean isShow() {
return StringUtils.isBlank(optionName) && StringUtils.isBlank(optionValue);
}
/**
* 判断当前动作是否需要展示某个Name的值
*/
private boolean isShowName() {
return !StringUtils.isBlank(optionName) && StringUtils.isBlank(optionValue);
}
private Collection<Field> findOptionFields(Matcher<String> optionNameMatcher) {
final Collection<Field> matchFields = new ArrayList<Field>();
for (final Field optionField : FieldUtils.getAllFields(GlobalOptions.class)) {
if (isMatchOptionAnnotation(optionField, optionNameMatcher)) {
matchFields.add(optionField);
}
}
return matchFields;
}
private Collection<String> findOptionNames(Matcher<String> optionNameMatcher) {
final Collection<String> matchOptionNames = new ArrayList<String>();
for (final Field optionField : FieldUtils.getAllFields(GlobalOptions.class)) {
if (isMatchOptionAnnotation(optionField, optionNameMatcher)) {
final Option optionAnnotation = optionField.getAnnotation(Option.class);
matchOptionNames.add(optionAnnotation.name());
}
}
return matchOptionNames;
}
private boolean isMatchOptionAnnotation(Field optionField, Matcher<String> optionNameMatcher) {
if (!optionField.isAnnotationPresent(Option.class)) {
return false;
}
final Option optionAnnotation = optionField.getAnnotation(Option.class);
return optionAnnotation != null && optionNameMatcher.matching(optionAnnotation.name());
}
private List<OptionVO> convertToOptionVOs(Collection<Field> fields) throws IllegalAccessException {
List<OptionVO> list = new ArrayList<OptionVO>();
for (Field field : fields) {
list.add(convertToOptionVO(field));
}
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;
}
}
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;
import com.taobao.middleware.cli.annotations.Summary;
@Name("pwd")
@Summary("Return working directory name")
public class PwdCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
String path = new File("").getAbsolutePath();
process.appendResult(new PwdModel(path));
process.end();
}
}
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;
import com.taobao.arthas.core.util.SearchUtils;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
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.Option;
import com.taobao.middleware.cli.annotations.Summary;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
/**
* 恢复所有增强类<br/>
*
* @author vlinux on 15/5/29.
*/
@Name("reset")
@Summary("Reset all the enhanced classes")
@Description(Constants.EXAMPLE +
" reset\n" +
" reset *List\n" +
" reset -E .*List\n")
public class ResetCommand extends AnnotatedCommand {
private String classPattern;
private boolean isRegEx = false;
@Argument(index = 0, argName = "class-pattern", required = false)
@Description("Path and classname of Pattern Matching")
public void setClassPattern(String classPattern) {
this.classPattern = classPattern;
}
@Option(shortName = "E", longName = "regex", flag = true)
@Description("Enable regular expression to match (wildcard matching by default)")
public void setRegEx(boolean regEx) {
isRegEx = regEx;
}
@Override
public void process(CommandProcess process) {
Instrumentation inst = process.session().getInstrumentation();
Matcher matcher = SearchUtils.classNameMatcher(classPattern, isRegEx);
try {
EnhancerAffect enhancerAffect = Enhancer.reset(inst, matcher);
process.appendResult(new ResetModel(enhancerAffect));
process.end();
} catch (UnmodifiableClassException e) {
// ignore
process.end();
}
}
}
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;
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.alibaba.arthas.tunnel.client.TunnelClient;
/**
* 查看会话状态命令
*
* @author vlinux on 15/5/3.
*/
@Name("session")
@Summary("Display current session information")
public class SessionCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
SessionModel result = new SessionModel();
Session session = process.session();
result.setJavaPid(session.getPid());
result.setSessionId(session.getSessionId());
//tunnel
TunnelClient tunnelClient = ArthasBootstrap.getInstance().getTunnelClient();
if (tunnelClient != null) {
String id = tunnelClient.getId();
if (id != null) {
result.setAgentId(id);
}
result.setTunnelServer(tunnelClient.getTunnelServerUrl());
result.setTunnelConnected(tunnelClient.isConnected());
}
//statUrl
String statUrl = UserStatUtil.getStatUrl();
result.setStatUrl(statUrl);
process.appendResult(result);
process.end();
}
}
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.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.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
/**
* @author hengyunabc 2019-07-05
*/
@Name("stop")
@Summary("Stop/Shutdown Arthas server and exit the console.")
public class StopCommand extends AnnotatedCommand {
private static final Logger logger = LoggerFactory.getLogger(StopCommand.class);
@Override
public void process(CommandProcess process) {
shutdown(process);
}
private static void shutdown(CommandProcess process) {
ArthasBootstrap arthasBootstrap = ArthasBootstrap.getInstance();
try {
// 退出之前需要重置所有的增强类
process.appendResult(new MessageModel("Resetting all enhanced classes ..."));
EnhancerAffect enhancerAffect = arthasBootstrap.reset();
process.appendResult(new ResetModel(enhancerAffect));
process.appendResult(new ShutdownModel(true, "Arthas Server is going to shutdown..."));
} 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();
arthasBootstrap.destroy();
}
}
}
package com.taobao.arthas.core.command.basic1000;
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;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.StringUtils;
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;
/**
* @author hengyunabc 2018-11-09
*
*/
@Name("sysenv")
@Summary("Display the system env.")
@Description(Constants.EXAMPLE + " sysenv\n" + " sysenv USER\n" + Constants.WIKI + Constants.WIKI_HOME + "sysenv")
public class SystemEnvCommand extends AnnotatedCommand {
private String envName;
@Argument(index = 0, argName = "env-name", required = false)
@Description("env name")
public void setOptionName(String envName) {
this.envName = envName;
}
@Override
public void process(CommandProcess process) {
try {
SystemEnvModel result = new SystemEnvModel();
if (StringUtils.isBlank(envName)) {
// show all system env
result.putAll(System.getenv());
} else {
// view the specified system env
String value = System.getenv(envName);
result.put(envName, value);
}
process.appendResult(result);
process.end();
} catch (Throwable t) {
process.end(-1, "Error during setting system env: " + t.getMessage());
}
}
/**
* First, try to complete with the sysenv command scope. If completion is
* failed, delegates to super class.
*
* @param completion
* the completion object
*/
@Override
public void complete(Completion completion) {
CompletionUtils.complete(completion, System.getenv().keySet());
}
}
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.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;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.StringUtils;
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;
/**
* @author ralf0131 2017-01-09 14:03.
*/
@Name("sysprop")
@Summary("Display, and change the system properties.")
@Description(Constants.EXAMPLE + " sysprop\n"+ " sysprop file.encoding\n" + " sysprop production.mode true\n" +
Constants.WIKI + Constants.WIKI_HOME + "sysprop")
public class SystemPropertyCommand extends AnnotatedCommand {
private String propertyName;
private String propertyValue;
@Argument(index = 0, argName = "property-name", required = false)
@Description("property name")
public void setOptionName(String propertyName) {
this.propertyName = propertyName;
}
@Argument(index = 1, argName = "property-value", required = false)
@Description("property value")
public void setOptionValue(String propertyValue) {
this.propertyValue = propertyValue;
}
@Override
public void process(CommandProcess process) {
try {
if (StringUtils.isBlank(propertyName) && StringUtils.isBlank(propertyValue)) {
// show all system properties
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.end(1, "There is no property with the key " + propertyName);
return;
} else {
process.appendResult(new SystemPropertyModel(propertyName, value));
}
} else {
// change system property
System.setProperty(propertyName, propertyValue);
process.appendResult(new MessageModel("Successfully changed the system property."));
process.appendResult(new SystemPropertyModel(propertyName, System.getProperty(propertyName)));
}
process.end();
} catch (Throwable t) {
process.end(-1, "Error during setting system property: " + t.getMessage());
}
}
/**
* First, try to complete with the sysprop command scope.
* If completion is failed, delegates to super class.
* @param completion the completion object
*/
@Override
public void complete(Completion completion) {
CompletionUtils.complete(completion, System.getProperties().stringPropertyNames());
}
}
package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.middleware.cli.annotations.*;
/**
* @author min.yang
*/
@Name("tee")
@Summary("tee command for pipes." )
@Description(Constants.EXAMPLE +
" sysprop | tee /path/to/logfile | grep java \n" +
" sysprop | tee -a /path/to/logfile | grep java \n"
+ Constants.WIKI + Constants.WIKI_HOME + "tee")
public class TeeCommand extends AnnotatedCommand {
private String filePath;
private boolean append;
@Argument(index = 0, argName = "file", required = false)
@Description("File path")
public void setFilePath(String filePath) {
this.filePath = filePath;
}
@Option(shortName = "a", longName = "append", flag = true)
@Description("Append to file")
public void setRegEx(boolean append) {
this.append = append;
}
@Override
public void process(CommandProcess process) {
process.end(-1, "The tee command only for pipes. See 'tee --help'");
}
public String getFilePath() {
return filePath;
}
public boolean isAppend() {
return append;
}
}
package com.taobao.arthas.core.command.basic1000;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.alibaba.arthas.deps.org.slf4j.Logger;
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.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;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.StringUtils;
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;
/**
* vmoption command
*
* @author hengyunabc 2019-09-02
*
*/
// @formatter:off
@Name("vmoption")
@Summary("Display, and update the vm diagnostic options.")
@Description("\nExamples:\n" +
" vmoption\n" +
" vmoption PrintGC\n" +
" vmoption PrintGC true\n" +
" vmoption PrintGCDetails true\n" +
Constants.WIKI + Constants.WIKI_HOME + "vmoption")
//@formatter:on
public class VMOptionCommand extends AnnotatedCommand {
private static final Logger logger = LoggerFactory.getLogger(VMOptionCommand.class);
private String name;
private String value;
@Argument(index = 0, argName = "name", required = false)
@Description("VMOption name")
public void setOptionName(String name) {
this.name = name;
}
@Argument(index = 1, argName = "value", required = false)
@Description("VMOption value")
public void setOptionValue(String value) {
this.value = value;
}
@Override
public void process(CommandProcess process) {
run(process, name, value);
}
private static void run(CommandProcess process, String name, String value) {
try {
HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory
.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
if (StringUtils.isBlank(name) && StringUtils.isBlank(value)) {
// show all options
process.appendResult(new VMOptionModel(hotSpotDiagnosticMXBean.getDiagnosticOptions()));
} else if (StringUtils.isBlank(value)) {
// view the specified option
VMOption option = hotSpotDiagnosticMXBean.getVMOption(name);
if (option == null) {
process.end(-1, "In order to change the system properties, you must specify the property value.");
return;
} else {
process.appendResult(new VMOptionModel(Collections.singletonList(option)));
}
} else {
VMOption vmOption = hotSpotDiagnosticMXBean.getVMOption(name);
String originValue = vmOption.getValue();
// change vm option
hotSpotDiagnosticMXBean.setVMOption(name, value);
process.appendResult(new MessageModel("Successfully updated the vm option."));
process.appendResult(new VMOptionModel(new ChangeResultVO(name, originValue,
hotSpotDiagnosticMXBean.getVMOption(name).getValue())));
}
process.end();
} catch (Throwable t) {
logger.error("Error during setting vm option", t);
process.end(-1, "Error during setting vm option: " + t.getMessage());
}
}
@Override
public void complete(Completion completion) {
HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory
.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
List<VMOption> diagnosticOptions = hotSpotDiagnosticMXBean.getDiagnosticOptions();
List<String> names = new ArrayList<String>(diagnosticOptions.size());
for (VMOption option : diagnosticOptions) {
names.add(option.getName());
}
CompletionUtils.complete(completion, names);
}
}
package com.taobao.arthas.core.command.basic1000;
import com.taobao.arthas.core.command.model.VersionModel;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.ArthasBanner;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
/**
* 输出版本
*
* @author vlinux
*/
@Name("version")
@Summary("Display Arthas version")
public class VersionCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
VersionModel result = new VersionModel();
result.setVersion(ArthasBanner.version());
process.appendResult(result);
process.end();
}
}
package com.taobao.arthas.core.command.express;
import java.util.Map;
import com.taobao.arthas.core.GlobalOptions;
import ognl.ObjectPropertyAccessor;
import ognl.OgnlException;
/**
*
* @author hengyunabc 2022-03-24
*
*/
public class ArthasObjectPropertyAccessor extends ObjectPropertyAccessor {
@Override
public Object setPossibleProperty(Map context, Object target, String name, Object value) throws OgnlException {
if (GlobalOptions.strict) {
throw new IllegalAccessError(GlobalOptions.STRICT_MESSAGE);
}
return super.setPossibleProperty(context, target, name, value);
}
}
package com.taobao.arthas.core.command.express;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import ognl.ClassResolver;
/**
*
* @author hengyunabc 2018-10-18
* @see ognl.DefaultClassResolver
*/
public class ClassLoaderClassResolver implements ClassResolver {
private ClassLoader classLoader;
private Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>(101);
public ClassLoaderClassResolver(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public Class<?> classForName(String className, @SuppressWarnings("rawtypes") Map context)
throws ClassNotFoundException {
Class<?> result = null;
if ((result = classes.get(className)) == null) {
try {
result = classLoader.loadClass(className);
} catch (ClassNotFoundException ex) {
if (className.indexOf('.') == -1) {
result = Class.forName("java.lang." + className);
classes.put("java.lang." + className, result);
}
}
if (result == null) {
return null;
}
classes.put(className, result);
}
return result;
}
}
package com.taobao.arthas.core.command.express;
import ognl.ClassResolver;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author diecui1202 on 2017/9/29.
* @see ognl.DefaultClassResolver
*/
public class CustomClassResolver implements ClassResolver {
public static final CustomClassResolver customClassResolver = new CustomClassResolver();
private Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>(101);
private CustomClassResolver() {
}
public Class<?> classForName(String className, Map context) throws ClassNotFoundException {
Class<?> result = null;
if ((result = classes.get(className)) == null) {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
result = classLoader.loadClass(className);
} else {
result = Class.forName(className);
}
} catch (ClassNotFoundException ex) {
if (className.indexOf('.') == -1) {
result = Class.forName("java.lang." + className);
classes.put("java.lang." + className, result);
}
}
classes.put(className, result);
}
return result;
}
}
package com.taobao.arthas.core.command.express;
/**
* 表达式
* Created by vlinux on 15/5/20.
*/
public interface Express {
/**
* 根据表达式获取值
*
* @param express 表达式
* @return 表达式运算后的值
* @throws ExpressException 表达式运算出错
*/
Object get(String express) throws ExpressException;
/**
* 根据表达式判断是与否
*
* @param express 表达式
* @return 表达式运算后的布尔值
* @throws ExpressException 表达式运算出错
*/
boolean is(String express) throws ExpressException;
/**
* 绑定对象
*
* @param object 待绑定对象
* @return this
*/
Express bind(Object object);
/**
* 绑定变量
*
* @param name 变量名
* @param value 变量值
* @return this
*/
Express bind(String name, Object value);
/**
* 重置整个表达式
*
* @return this
*/
Express reset();
}
package com.taobao.arthas.core.command.express;
/**
* 表达式异常
* Created by vlinux on 15/5/20.
*/
public class ExpressException extends Exception {
private final String express;
/**
* 表达式异常
*
* @param express 原始表达式
* @param cause 异常原因
*/
public ExpressException(String express, Throwable cause) {
super(cause);
this.express = express;
}
/**
* 获取表达式
*
* @return 返回出问题的表达式
*/
public String getExpress() {
return express;
}
}
package com.taobao.arthas.core.command.express;
/**
* ExpressFactory
* @author ralf0131 2017-01-04 14:40.
* @author hengyunabc 2018-10-08
*/
public class ExpressFactory {
private static final ThreadLocal<Express> expressRef = new ThreadLocal<Express>() {
@Override
protected Express initialValue() {
return new OgnlExpress();
}
};
/**
* get ThreadLocal Express Object
* @param object
* @return
*/
public static Express threadLocalExpress(Object object) {
return expressRef.get().reset().bind(object);
}
public static Express unpooledExpress(ClassLoader classloader) {
if (classloader == null) {
classloader = ClassLoader.getSystemClassLoader();
}
return new OgnlExpress(new ClassLoaderClassResolver(classloader));
}
}
\ No newline at end of file
package com.taobao.arthas.core.command.express;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import ognl.ClassResolver;
import ognl.DefaultMemberAccess;
import ognl.MemberAccess;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlRuntime;
/**
* @author ralf0131 2017-01-04 14:41.
* @author hengyunabc 2018-10-18
*/
public class OgnlExpress implements Express {
private static final MemberAccess MEMBER_ACCESS = new DefaultMemberAccess(true);
private static final Logger logger = LoggerFactory.getLogger(OgnlExpress.class);
private static final ArthasObjectPropertyAccessor OBJECT_PROPERTY_ACCESSOR = new ArthasObjectPropertyAccessor();
private Object bindObject;
private final OgnlContext context;
public OgnlExpress() {
this(CustomClassResolver.customClassResolver);
}
public OgnlExpress(ClassResolver classResolver) {
OgnlRuntime.setPropertyAccessor(Object.class, OBJECT_PROPERTY_ACCESSOR);
context = new OgnlContext();
context.setClassResolver(classResolver);
// allow private field access
context.setMemberAccess(MEMBER_ACCESS);
}
@Override
public Object get(String express) throws ExpressException {
try {
return Ognl.getValue(express, context, bindObject);
} catch (Exception e) {
logger.error("Error during evaluating the expression:", e);
throw new ExpressException(express, e);
}
}
@Override
public boolean is(String express) throws ExpressException {
final Object ret = get(express);
return ret instanceof Boolean && (Boolean) ret;
}
@Override
public Express bind(Object object) {
this.bindObject = object;
return this;
}
@Override
public Express bind(String name, Object value) {
context.put(name, value);
return this;
}
@Override
public Express reset() {
context.clear();
context.setClassResolver(CustomClassResolver.customClassResolver);
// allow private field access
context.setMemberAccess(MEMBER_ACCESS);
return this;
}
}
package com.taobao.arthas.core.command.hidden;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.middleware.cli.annotations.Hidden;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
/**
* @author vlinux on 02/11/2016.
*/
@Name("july")
@Summary("don't ask why")
@Hidden
public class JulyCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write(new String($$())).write("\n").end();
}
private static byte[] $$() {
return new byte[]{
0x49, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x69, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74,
0x20, 0x79, 0x6f, 0x75, 0x20, 0x64, 0x69, 0x64, 0x0a, 0x49, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74,
0x20, 0x6c, 0x65, 0x74, 0x20, 0x6d, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x43, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6d,
0x79, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x20, 0x73, 0x6f, 0x20, 0x6d, 0x75, 0x63, 0x68, 0x20, 0x6d, 0x69, 0x73,
0x65, 0x72, 0x79, 0x0a, 0x49, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x72, 0x65, 0x61,
0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x61, 0x79, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x64, 0x69, 0x64, 0x0a, 0x59,
0x6f, 0x75, 0x20, 0x66, 0x65, 0x6c, 0x6c, 0x20, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x72, 0x64, 0x0a, 0x0a, 0x49, 0x20,
0x76, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x72, 0x64,
0x20, 0x77, 0x61, 0x79, 0x0a, 0x54, 0x6f, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x69,
0x74, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x66, 0x61, 0x72, 0x0a, 0x0a, 0x42, 0x65, 0x63,
0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72,
0x20, 0x73, 0x74, 0x72, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x66, 0x61, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d,
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x64, 0x65, 0x77, 0x61, 0x6c, 0x6b, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75,
0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64,
0x20, 0x74, 0x6f, 0x20, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x66,
0x65, 0x20, 0x73, 0x69, 0x64, 0x65, 0x20, 0x73, 0x6f, 0x20, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x20, 0x74, 0x20, 0x67,
0x65, 0x74, 0x20, 0x68, 0x75, 0x72, 0x74, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x72, 0x64, 0x20,
0x74, 0x6f, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6d,
0x65, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x61, 0x72, 0x6f,
0x75, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79,
0x6f, 0x75, 0x0a, 0x49, 0x20, 0x61, 0x6d, 0x20, 0x61, 0x66, 0x72, 0x61, 0x69, 0x64, 0x0a, 0x0a, 0x49, 0x20, 0x6c,
0x6f, 0x73, 0x65, 0x20, 0x6d, 0x79, 0x20, 0x77, 0x61, 0x79, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x73,
0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72,
0x65, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x74, 0x20, 0x6f, 0x75, 0x74, 0x0a,
0x49, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x72, 0x79, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73,
0x65, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x20, 0x77,
0x65, 0x61, 0x6b, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x65, 0x79, 0x65,
0x73, 0x0a, 0x49, 0x20, 0x6d, 0x20, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x61, 0x6b,
0x65, 0x0a, 0x41, 0x20, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x20, 0x6c, 0x61, 0x75, 0x67, 0x68, 0x20,
0x65, 0x76, 0x65, 0x72, 0x79, 0x64, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x79, 0x20, 0x6c, 0x69, 0x66, 0x65,
0x0a, 0x4d, 0x79, 0x20, 0x68, 0x65, 0x61, 0x72, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x6f, 0x73,
0x73, 0x69, 0x62, 0x6c, 0x79, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x0a, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x69, 0x74,
0x20, 0x77, 0x61, 0x73, 0x6e, 0x27, 0x74, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x20, 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x20,
0x74, 0x6f, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x0a, 0x42, 0x65, 0x63, 0x61,
0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20,
0x73, 0x74, 0x72, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x66, 0x61, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x64, 0x65, 0x77, 0x61, 0x6c, 0x6b, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73,
0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64, 0x20,
0x74, 0x6f, 0x20, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x66, 0x65,
0x20, 0x73, 0x69, 0x64, 0x65, 0x20, 0x73, 0x6f, 0x20, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x20, 0x74, 0x20, 0x67, 0x65,
0x74, 0x20, 0x68, 0x75, 0x72, 0x74, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79,
0x6f, 0x75, 0x0a, 0x49, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x72, 0x64, 0x20, 0x74,
0x6f, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6d, 0x65,
0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x61, 0x72, 0x6f, 0x75,
0x6e, 0x64, 0x20, 0x6d, 0x65, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f,
0x75, 0x0a, 0x49, 0x20, 0x61, 0x6d, 0x20, 0x61, 0x66, 0x72, 0x61, 0x69, 0x64, 0x0a, 0x0a, 0x49, 0x20, 0x77, 0x61,
0x74, 0x63, 0x68, 0x65, 0x64, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x64, 0x69, 0x65, 0x0a, 0x49, 0x20, 0x68, 0x65, 0x61,
0x72, 0x64, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x72, 0x79, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6e, 0x69,
0x67, 0x68, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x0a, 0x49,
0x20, 0x77, 0x61, 0x73, 0x20, 0x73, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x6e, 0x67, 0x0a, 0x59, 0x6f, 0x75, 0x20, 0x73,
0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x62, 0x65,
0x74, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x6f,
0x6e, 0x20, 0x6d, 0x65, 0x0a, 0x59, 0x6f, 0x75, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x6f, 0x75,
0x67, 0x68, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a,
0x59, 0x6f, 0x75, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x73, 0x61, 0x77, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x70,
0x61, 0x69, 0x6e, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x49, 0x20, 0x63, 0x72, 0x79, 0x20, 0x69,
0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
0x20, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x0a, 0x46, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65,
0x20, 0x64, 0x61, 0x6d, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73,
0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x73, 0x74,
0x72, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x66, 0x61, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68,
0x65, 0x20, 0x73, 0x69, 0x64, 0x65, 0x77, 0x61, 0x6c, 0x6b, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20,
0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49, 0x20, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x6f,
0x20, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x66, 0x65, 0x20, 0x73,
0x69, 0x64, 0x65, 0x20, 0x73, 0x6f, 0x20, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x20, 0x74, 0x20, 0x67, 0x65, 0x74, 0x20,
0x68, 0x75, 0x72, 0x74, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75,
0x0a, 0x49, 0x20, 0x74, 0x72, 0x79, 0x20, 0x6d, 0x79, 0x20, 0x68, 0x61, 0x72, 0x64, 0x65, 0x73, 0x74, 0x20, 0x6a,
0x75, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79,
0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f,
0x75, 0x0a, 0x49, 0x20, 0x64, 0x6f, 0x6e, 0x20, 0x74, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x20, 0x68, 0x6f, 0x77, 0x20,
0x74, 0x6f, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20,
0x69, 0x6e, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49,
0x20, 0x6d, 0x20, 0x61, 0x73, 0x68, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x79, 0x20, 0x6c, 0x69,
0x66, 0x65, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x69, 0x74, 0x20, 0x73, 0x20, 0x65, 0x6d, 0x70,
0x74, 0x79, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x49,
0x20, 0x61, 0x6d, 0x20, 0x61, 0x66, 0x72, 0x61, 0x69, 0x64, 0x0a, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65,
0x20, 0x6f, 0x66, 0x20, 0x79, 0x6f, 0x75, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20,
0x79, 0x6f, 0x75, 0x0a, 0x2e, 0x2e, 0x2e, 0x0a, /*0x0a, 0x66, 0x6f, 0x72, 0x20, 0x6a, 0x75, 0x6c, 0x79, 0x0a, 0x0a,*/
};
}
}
package com.taobao.arthas.core.command.hidden;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.ArthasBanner;
import com.taobao.middleware.cli.annotations.Hidden;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
/**
* 工具介绍<br/>
* 感谢
*
* @author vlinux on 15/9/1.
*/
@Name("thanks")
@Summary("Credits to all personnel and organization who either contribute or help to this product. Thanks you all!")
@Hidden
public class ThanksCommand extends AnnotatedCommand {
@Override
public void process(CommandProcess process) {
process.write(ArthasBanner.credit()).write("\n").end();
}
}
package com.taobao.arthas.core.command.klass100;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.core.util.FileUtils;
import com.taobao.arthas.core.util.LogUtil;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author beiwei30 on 25/11/2016.
*/
class ClassDumpTransformer implements ClassFileTransformer {
private static final Logger logger = LoggerFactory.getLogger(ClassDumpTransformer.class);
private Set<Class<?>> classesToEnhance;
private Map<Class<?>, File> dumpResult;
private File arthasLogHome;
private File directory;
public ClassDumpTransformer(Set<Class<?>> classesToEnhance) {
this(classesToEnhance, null);
}
public ClassDumpTransformer(Set<Class<?>> classesToEnhance, File directory) {
this.classesToEnhance = classesToEnhance;
this.dumpResult = new HashMap<Class<?>, File>();
this.arthasLogHome = new File(LogUtil.loggingDir());
this.directory = directory;
}
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws IllegalClassFormatException {
if (classesToEnhance.contains(classBeingRedefined)) {
dumpClassIfNecessary(classBeingRedefined, classfileBuffer);
}
return null;
}
public Map<Class<?>, File> getDumpResult() {
return dumpResult;
}
private void dumpClassIfNecessary(Class<?> clazz, byte[] data) {
String className = clazz.getName();
ClassLoader classLoader = clazz.getClassLoader();
String classDumpDir = "classdump";
// 创建类所在的包路径
File dumpDir = null;
if (directory != null) {
dumpDir = directory;
} else {
dumpDir = new File(arthasLogHome, classDumpDir);
}
if (!dumpDir.mkdirs() && !dumpDir.exists()) {
logger.warn("create dump directory:{} failed.", dumpDir.getAbsolutePath());
return;
}
String fileName;
if (classLoader != null) {
fileName = classLoader.getClass().getName() + "-" + Integer.toHexString(classLoader.hashCode()) +
File.separator + className.replace(".", File.separator) + ".class";
} else {
fileName = className.replace(".", File.separator) + ".class";
}
File dumpClassFile = new File(dumpDir, fileName);
// 将类字节码写入文件
try {
FileUtils.writeByteArrayToFile(dumpClassFile, data);
dumpResult.put(clazz, dumpClassFile);
} catch (IOException e) {
logger.warn("dump class:{} to file {} failed.", className, dumpClassFile, e);
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment