HTTP API support plain txt ObjectView #2261

pull/2262/head
hengyunabc 2 years ago
parent e749188e53
commit 1d9908752f

@ -293,7 +293,7 @@ public class ClassLoaderCommand extends AnnotatedCommand {
try {
Class<?> clazz = targetClassLoader.loadClass(this.loadClass);
process.appendResult(new MessageModel("load class success."));
ClassDetailVO classInfo = ClassUtils.createClassInfo(clazz, false);
ClassDetailVO classInfo = ClassUtils.createClassInfo(clazz, false, null);
process.appendResult(new ClassLoaderModel().setLoadClass(classInfo));
} catch (Throwable e) {

@ -11,6 +11,7 @@ import com.taobao.arthas.core.command.express.Express;
import com.taobao.arthas.core.command.express.ExpressException;
import com.taobao.arthas.core.command.express.ExpressFactory;
import com.taobao.arthas.core.command.model.ClassLoaderVO;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.OgnlModel;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
@ -103,8 +104,7 @@ public class OgnlCommand extends AnnotatedCommand {
try {
Object value = unpooledExpress.get(express);
OgnlModel ognlModel = new OgnlModel()
.setValue(value)
.setExpand(expand);
.setValue(new ObjectVO(value, expand));
process.appendResult(ognlModel);
process.end();
} catch (ExpressException e) {

@ -140,8 +140,8 @@ public class SearchClassCommand extends AnnotatedCommand {
return;
}
for (Class<?> clazz : matchedClasses) {
ClassDetailVO classInfo = ClassUtils.createClassInfo(clazz, isField);
process.appendResult(new SearchClassModel(classInfo, isDetail, isField, expand));
ClassDetailVO classInfo = ClassUtils.createClassInfo(clazz, isField, expand);
process.appendResult(new SearchClassModel(classInfo, isDetail, isField));
}
} else {
int pageSize = 256;

@ -8,7 +8,7 @@ public class FieldVO {
private String type;
private String modifier;
private String[] annotations;
private Object value;
private ObjectVO value;
private boolean isStatic;
public String getName() {
@ -35,11 +35,11 @@ public class FieldVO {
this.modifier = modifier;
}
public Object getValue() {
public ObjectVO getValue() {
return value;
}
public void setValue(Object value) {
public void setValue(ObjectVO value) {
this.value = value;
}
@ -58,4 +58,5 @@ public class FieldVO {
public void setStatic(boolean aStatic) {
isStatic = aStatic;
}
}

@ -9,8 +9,8 @@ import java.util.Collection;
public class GetStaticModel extends ResultModel {
private Collection<ClassVO> matchedClasses;
private String fieldName;
private ObjectVO field;
private int expand;
private Collection<ClassLoaderVO> matchedClassLoaders;
private String classLoaderClass;
@ -18,8 +18,8 @@ public class GetStaticModel extends ResultModel {
}
public GetStaticModel(String fieldName, Object fieldValue, int expand) {
this.field = new ObjectVO(fieldName, fieldValue);
this.expand = expand;
this.fieldName = fieldName;
this.field = new ObjectVO(fieldValue, expand);
}
public GetStaticModel(Collection<ClassVO> matchedClasses) {
@ -34,20 +34,20 @@ public class GetStaticModel extends ResultModel {
this.field = field;
}
public Collection<ClassVO> getMatchedClasses() {
return matchedClasses;
public String getFieldName() {
return fieldName;
}
public void setMatchedClasses(Collection<ClassVO> matchedClasses) {
this.matchedClasses = matchedClasses;
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public int getExpand() {
return expand;
public Collection<ClassVO> getMatchedClasses() {
return matchedClasses;
}
public void setExpand(int expand) {
this.expand = expand;
public void setMatchedClasses(Collection<ClassVO> matchedClasses) {
this.matchedClasses = matchedClasses;
}
public String getClassLoaderClass() {

@ -1,34 +1,55 @@
package com.taobao.arthas.core.command.model;
/**
* @author gongdewei 2020/4/29
* <pre>
* json
* https://github.com/alibaba/arthas/issues/2261
* </pre>
*
* @author hengyunabc 2022-08-24
*
*/
public class ObjectVO {
private String name;
private Object value;
private Object object;
private Integer expand;
public ObjectVO(String name, Object value) {
this.name = name;
this.value = value;
public ObjectVO(Object object, Integer expand) {
this.object = object;
this.expand = expand;
}
public ObjectVO(Object value) {
this.value = value;
public static ObjectVO[] array(Object[] objects, Integer expand) {
ObjectVO[] result = new ObjectVO[objects.length];
for (int i = 0; i < objects.length; ++i) {
result[i] = new ObjectVO(objects[i], expand);
}
return result;
}
public String getName() {
return name;
public int expandOrDefault() {
if (expand != null) {
return expand;
}
return 1;
}
public void setName(String name) {
this.name = name;
public boolean needExpand() {
return null != expand && expand > 0;
}
public Object getValue() {
return value;
public Object getObject() {
return object;
}
public void setValue(Object value) {
this.value = value;
public void setObject(Object object) {
this.object = object;
}
public Integer getExpand() {
return expand;
}
public void setExpand(Integer expand) {
this.expand = expand;
}
}

@ -7,8 +7,7 @@ import java.util.Collection;
* @author gongdewei 2020/4/29
*/
public class OgnlModel extends ResultModel {
private Object value;
private int expand = 1;
private ObjectVO value;
private Collection<ClassLoaderVO> matchedClassLoaders;
private String classLoaderClass;
@ -19,24 +18,15 @@ public class OgnlModel extends ResultModel {
return "ognl";
}
public Object getValue() {
public ObjectVO getValue() {
return value;
}
public OgnlModel setValue(Object value) {
public OgnlModel setValue(ObjectVO value) {
this.value = value;
return this;
}
public int getExpand() {
return expand;
}
public OgnlModel setExpand(int expand) {
this.expand = expand;
return this;
}
public String getClassLoaderClass() {
return classLoaderClass;
}

@ -11,7 +11,6 @@ public class SearchClassModel extends ResultModel {
private ClassDetailVO classInfo;
private boolean withField;
private boolean detailed;
private Integer expand;
private List<String> classNames;
private int segment;
@ -21,11 +20,10 @@ public class SearchClassModel extends ResultModel {
public SearchClassModel() {
}
public SearchClassModel(ClassDetailVO classInfo, boolean detailed, boolean withField, Integer expand) {
public SearchClassModel(ClassDetailVO classInfo, boolean detailed, boolean withField) {
this.classInfo = classInfo;
this.detailed = detailed;
this.withField = withField;
this.expand = expand;
}
public SearchClassModel(List<String> classNames, int segment) {
@ -70,10 +68,6 @@ public class SearchClassModel extends ResultModel {
return withField;
}
public Integer getExpand() {
return expand;
}
public String getClassLoaderClass() {
return classLoaderClass;
}

@ -15,9 +15,9 @@ public class TimeFragmentVO {
private String object;
private String className;
private String methodName;
private Object[] params;
private Object returnObj;
private Throwable throwExp;
private ObjectVO[] params;
private ObjectVO returnObj;
private ObjectVO throwExp;
public TimeFragmentVO() {
}
@ -94,29 +94,29 @@ public class TimeFragmentVO {
return this;
}
public Object[] getParams() {
public ObjectVO[] getParams() {
return params;
}
public TimeFragmentVO setParams(Object[] params) {
public TimeFragmentVO setParams(ObjectVO[] params) {
this.params = params;
return this;
}
public Object getReturnObj() {
public ObjectVO getReturnObj() {
return returnObj;
}
public TimeFragmentVO setReturnObj(Object returnObj) {
public TimeFragmentVO setReturnObj(ObjectVO returnObj) {
this.returnObj = returnObj;
return this;
}
public Throwable getThrowExp() {
public ObjectVO getThrowExp() {
return throwExp;
}
public TimeFragmentVO setThrowExp(Throwable throwExp) {
public TimeFragmentVO setThrowExp(ObjectVO throwExp) {
this.throwExp = throwExp;
return this;
}

@ -24,10 +24,10 @@ public class TimeTunnelModel extends ResultModel {
//重放执行的次数
private Integer replayNo;
private Object watchValue;
private ObjectVO watchValue;
//search: tt -s {} -w {}
private Map<Integer, Object> watchResults;
private Map<Integer, ObjectVO> watchResults;
private Integer expand;
@ -75,20 +75,20 @@ public class TimeTunnelModel extends ResultModel {
return this;
}
public Object getWatchValue() {
public ObjectVO getWatchValue() {
return watchValue;
}
public TimeTunnelModel setWatchValue(Object watchValue) {
public TimeTunnelModel setWatchValue(ObjectVO watchValue) {
this.watchValue = watchValue;
return this;
}
public Map<Integer, Object> getWatchResults() {
public Map<Integer, ObjectVO> getWatchResults() {
return watchResults;
}
public TimeTunnelModel setWatchResults(Map<Integer, Object> watchResults) {
public TimeTunnelModel setWatchResults(Map<Integer, ObjectVO> watchResults) {
this.watchResults = watchResults;
return this;
}

@ -8,8 +8,7 @@ import java.util.Collection;
*
*/
public class VmToolModel extends ResultModel {
private Object value;
private int expand = 1;
private ObjectVO value;
private Collection<ClassLoaderVO> matchedClassLoaders;
private String classLoaderClass;
@ -20,24 +19,15 @@ public class VmToolModel extends ResultModel {
return "vmtool";
}
public Object getValue() {
public ObjectVO getValue() {
return value;
}
public VmToolModel setValue(Object value) {
public VmToolModel setValue(ObjectVO value) {
this.value = value;
return this;
}
public int getExpand() {
return expand;
}
public VmToolModel setExpand(int expand) {
this.expand = expand;
return this;
}
public String getClassLoaderClass() {
return classLoaderClass;
}

@ -11,9 +11,8 @@ public class WatchModel extends ResultModel {
private Date ts;
private double cost;
private Object value;
private ObjectVO value;
private Integer expand;
private Integer sizeLimit;
private String className;
private String methodName;
@ -39,7 +38,7 @@ public class WatchModel extends ResultModel {
return cost;
}
public Object getValue() {
public ObjectVO getValue() {
return value;
}
@ -47,22 +46,14 @@ public class WatchModel extends ResultModel {
this.cost = cost;
}
public void setValue(Object value) {
public void setValue(ObjectVO value) {
this.value = value;
}
public void setExpand(Integer expand) {
this.expand = expand;
}
public void setSizeLimit(Integer sizeLimit) {
this.sizeLimit = sizeLimit;
}
public Integer getExpand() {
return expand;
}
public Integer getSizeLimit() {
return sizeLimit;
}

@ -88,7 +88,7 @@ public class TimeTunnelAdviceListener extends AdviceListenerAdapter {
int index = command.putTimeTunnel(timeTunnel);
TimeFragmentVO timeFragmentVO = TimeTunnelCommand.createTimeFragmentVO(index, timeTunnel);
TimeFragmentVO timeFragmentVO = TimeTunnelCommand.createTimeFragmentVO(index, timeTunnel, command.getExpand());
TimeTunnelModel timeTunnelModel = new TimeTunnelModel()
.setTimeFragmentList(Collections.singletonList(timeFragmentVO))
.setFirst(isFirst);

@ -10,6 +10,7 @@ import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.express.ExpressException;
import com.taobao.arthas.core.command.express.ExpressFactory;
import com.taobao.arthas.core.command.model.MessageModel;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.RowAffectModel;
import com.taobao.arthas.core.command.model.TimeFragmentVO;
import com.taobao.arthas.core.command.model.TimeTunnelModel;
@ -214,7 +215,6 @@ public class TimeTunnelCommand extends EnhancerCommand {
return numberOfLimit;
}
public int getReplayTimes() {
return replayTimes;
}
@ -223,6 +223,10 @@ public class TimeTunnelCommand extends EnhancerCommand {
return replayInterval;
}
public Integer getExpand() {
return expand;
}
private boolean hasWatchExpress() {
return !StringUtils.isEmpty(watchExpress);
}
@ -336,7 +340,7 @@ public class TimeTunnelCommand extends EnhancerCommand {
return;
}
TimeFragmentVO timeFragmentVO = createTimeFragmentVO(index, tf);
TimeFragmentVO timeFragmentVO = createTimeFragmentVO(index, tf, expand);
TimeTunnelModel timeTunnelModel = new TimeTunnelModel()
.setTimeFragment(timeFragmentVO)
.setExpand(expand)
@ -365,7 +369,7 @@ public class TimeTunnelCommand extends EnhancerCommand {
Object value = ExpressFactory.unpooledExpress(advice.getLoader()).bind(advice).get(watchExpress);
TimeTunnelModel timeTunnelModel = new TimeTunnelModel()
.setWatchValue(value)
.setWatchValue(new ObjectVO(value, expand))
.setExpand(expand)
.setSizeLimit(sizeLimit);
process.appendResult(timeTunnelModel);
@ -398,10 +402,10 @@ public class TimeTunnelCommand extends EnhancerCommand {
if (hasWatchExpress()) {
// 执行watchExpress
Map<Integer, Object> searchResults = new LinkedHashMap<Integer, Object>();
Map<Integer, ObjectVO> searchResults = new LinkedHashMap<Integer, ObjectVO>();
for (Map.Entry<Integer, TimeFragment> entry : matchingTimeSegmentMap.entrySet()) {
Object value = ExpressFactory.threadLocalExpress(entry.getValue().getAdvice()).get(watchExpress);
searchResults.put(entry.getKey(), value);
searchResults.put(entry.getKey(), new ObjectVO(value, expand));
}
TimeTunnelModel timeTunnelModel = new TimeTunnelModel()
@ -456,12 +460,12 @@ public class TimeTunnelCommand extends EnhancerCommand {
private List<TimeFragmentVO> createTimeTunnelVOList(Map<Integer, TimeFragment> timeFragmentMap) {
List<TimeFragmentVO> timeFragmentList = new ArrayList<TimeFragmentVO>(timeFragmentMap.size());
for (Map.Entry<Integer, TimeFragment> entry : timeFragmentMap.entrySet()) {
timeFragmentList.add(createTimeFragmentVO(entry.getKey(), entry.getValue()));
timeFragmentList.add(createTimeFragmentVO(entry.getKey(), entry.getValue(), expand));
}
return timeFragmentList;
}
public static TimeFragmentVO createTimeFragmentVO(Integer index, TimeFragment tf) {
public static TimeFragmentVO createTimeFragmentVO(Integer index, TimeFragment tf, Integer expand) {
Advice advice = tf.getAdvice();
String object = advice.getTarget() == null
? "NULL"
@ -471,11 +475,11 @@ public class TimeTunnelCommand extends EnhancerCommand {
.setIndex(index)
.setTimestamp(tf.getGmtCreate())
.setCost(tf.getCost())
.setParams(advice.getParams())
.setParams(ObjectVO.array(advice.getParams(), expand))
.setReturn(advice.isAfterReturning())
.setReturnObj(advice.getReturnObj())
.setReturnObj(new ObjectVO(advice.getReturnObj(), expand))
.setThrow(advice.isAfterThrowing())
.setThrowExp(advice.getThrowExp())
.setThrowExp(new ObjectVO(advice.getThrowExp(), expand))
.setObject(object)
.setClassName(advice.getClazz().getName())
.setMethodName(advice.getMethod().getName());
@ -508,7 +512,7 @@ public class TimeTunnelCommand extends EnhancerCommand {
long beginTime = System.nanoTime();
//copy from tt record
TimeFragmentVO replayResult = createTimeFragmentVO(index, tf);
TimeFragmentVO replayResult = createTimeFragmentVO(index, tf, expand);
replayResult.setTimestamp(new Date())
.setCost(0)
.setReturn(false)
@ -522,13 +526,13 @@ public class TimeTunnelCommand extends EnhancerCommand {
double cost = (System.nanoTime() - beginTime) / 1000000.0;
replayResult.setCost(cost)
.setReturn(true)
.setReturnObj(returnObj);
.setReturnObj(new ObjectVO(returnObj, expand));
} catch (Throwable t) {
//throw exp
double cost = (System.nanoTime() - beginTime) / 1000000.0;
replayResult.setCost(cost)
.setThrow(true)
.setThrowExp(t);
.setThrowExp(new ObjectVO(t, expand));
}
TimeTunnelModel timeTunnelModel = new TimeTunnelModel()

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.monitor200;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.TimeFragmentVO;
import com.taobao.arthas.core.util.StringUtils;
import com.taobao.arthas.core.view.ObjectView;
@ -102,17 +103,17 @@ public class TimeTunnelTable {
.row("IS-EXCEPTION", "" + tf.isThrow());
}
public static void drawThrowException(TableElement table, TimeFragmentVO tf, boolean isNeedExpand, Integer expandLevel) {
public static void drawThrowException(TableElement table, TimeFragmentVO tf) {
if (tf.isThrow()) {
//noinspection ThrowableResultOfMethodCallIgnored
Throwable throwable = tf.getThrowExp();
if (isNeedExpand) {
table.row("THROW-EXCEPTION", new ObjectView(throwable, expandLevel).draw());
ObjectVO throwableVO = tf.getThrowExp();
if (throwableVO.needExpand()) {
table.row("THROW-EXCEPTION", new ObjectView(throwableVO).draw());
} else {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
try {
throwable.printStackTrace(printWriter);
((Throwable) throwableVO.getObject()).printStackTrace(printWriter);
table.row("THROW-EXCEPTION", stringWriter.toString());
} finally {
printWriter.close();
@ -121,22 +122,22 @@ public class TimeTunnelTable {
}
}
public static void drawReturnObj(TableElement table, TimeFragmentVO tf, boolean isNeedExpand, Integer expandLevel, Integer sizeLimit) {
public static void drawReturnObj(TableElement table, TimeFragmentVO tf, Integer sizeLimit) {
if (tf.isReturn()) {
if (isNeedExpand) {
table.row("RETURN-OBJ", new ObjectView(tf.getReturnObj(), expandLevel, sizeLimit).draw());
if (tf.getReturnObj().needExpand()) {
table.row("RETURN-OBJ", new ObjectView(sizeLimit, tf.getReturnObj()).draw());
} else {
table.row("RETURN-OBJ", "" + StringUtils.objectToString(tf.getReturnObj()));
}
}
}
public static void drawParameters(TableElement table, Object[] params, boolean isNeedExpand, Integer expandLevel) {
public static void drawParameters(TableElement table, ObjectVO[] params) {
if (params != null) {
int paramIndex = 0;
for (Object param : params) {
if (isNeedExpand) {
table.row("PARAMETERS[" + paramIndex++ + "]", new ObjectView(param, expandLevel).draw());
for (ObjectVO param : params) {
if (param.needExpand()) {
table.row("PARAMETERS[" + paramIndex++ + "]", new ObjectView(param).draw());
} else {
table.row("PARAMETERS[" + paramIndex++ + "]", "" + StringUtils.objectToString(param));
}
@ -149,12 +150,11 @@ public class TimeTunnelTable {
.style(Decoration.bold.bold()));
}
public static void drawWatchResults(TableElement table, Map<Integer, Object> watchResults, boolean isNeedExpand,
Integer expandLevel, Integer sizeLimit) {
for (Map.Entry<Integer, Object> entry : watchResults.entrySet()) {
Object value = entry.getValue();
public static void drawWatchResults(TableElement table, Map<Integer, ObjectVO> watchResults, Integer sizeLimit) {
for (Map.Entry<Integer, ObjectVO> entry : watchResults.entrySet()) {
ObjectVO objectVO = entry.getValue();
table.row("" + entry.getKey(), "" +
(isNeedExpand ? new ObjectView(value, expandLevel, sizeLimit).draw() : StringUtils.objectToString(value)));
(objectVO.needExpand() ? new ObjectView(sizeLimit, objectVO).draw() : StringUtils.objectToString(objectVO.getObject())));
}
}
@ -168,7 +168,7 @@ public class TimeTunnelTable {
.row("METHOD", methodName);
}
public static void drawPlayResult(TableElement table, Object returnObj, boolean isNeedExpand, int expandLevel,
public static void drawPlayResult(TableElement table, ObjectVO returnObjVO,
int sizeLimit, double cost) {
// 执行成功:输出成功状态
table.row("IS-RETURN", "" + true);
@ -176,28 +176,29 @@ public class TimeTunnelTable {
table.row("COST(ms)", "" + cost);
// 执行成功:输出成功结果
if (isNeedExpand) {
table.row("RETURN-OBJ", new ObjectView(returnObj, expandLevel, sizeLimit).draw());
if (returnObjVO.needExpand()) {
table.row("RETURN-OBJ", new ObjectView(sizeLimit, returnObjVO).draw());
} else {
table.row("RETURN-OBJ", "" + StringUtils.objectToString(returnObj));
table.row("RETURN-OBJ", "" + StringUtils.objectToString(returnObjVO.getObject()));
}
}
public static void drawPlayException(TableElement table, Throwable t, boolean isNeedExpand, int expandLevel) {
public static void drawPlayException(TableElement table, ObjectVO throwableVO) {
// 执行失败:输出失败状态
table.row("IS-RETURN", "" + false);
table.row("IS-EXCEPTION", "" + true);
// 执行失败:输出失败异常信息
Throwable cause;
Throwable t = (Throwable) throwableVO.getObject();
if (t instanceof InvocationTargetException) {
cause = t.getCause();
} else {
cause = t;
}
if (isNeedExpand) {
table.row("THROW-EXCEPTION", new ObjectView(cause, expandLevel).draw());
if (throwableVO.needExpand()) {
table.row("THROW-EXCEPTION", new ObjectView(cause, throwableVO.expandOrDefault()).draw());
} else {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);

@ -20,7 +20,7 @@ import com.taobao.arthas.core.command.express.Express;
import com.taobao.arthas.core.command.express.ExpressException;
import com.taobao.arthas.core.command.express.ExpressFactory;
import com.taobao.arthas.core.command.model.ClassLoaderVO;
import com.taobao.arthas.core.command.model.SearchClassModel;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.VmToolModel;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
@ -30,7 +30,6 @@ import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.ClassLoaderUtils;
import com.taobao.arthas.core.util.ClassUtils;
import com.taobao.arthas.core.util.SearchUtils;
import com.taobao.arthas.core.view.ObjectView;
import com.taobao.middleware.cli.annotations.DefaultValue;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
@ -218,7 +217,7 @@ public class VmToolCommand extends AnnotatedCommand {
}
}
VmToolModel vmToolModel = new VmToolModel().setValue(value).setExpand(expand);
VmToolModel vmToolModel = new VmToolModel().setValue(new ObjectVO(value, expand));
process.appendResult(vmToolModel);
process.end();
}

@ -6,6 +6,7 @@ import com.taobao.arthas.core.advisor.AccessPoint;
import com.taobao.arthas.core.advisor.Advice;
import com.taobao.arthas.core.advisor.AdviceListenerAdapter;
import com.taobao.arthas.core.advisor.ArthasMethod;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.WatchModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.LogUtil;
@ -88,8 +89,7 @@ class WatchAdviceListener extends AdviceListenerAdapter {
WatchModel model = new WatchModel();
model.setTs(new Date());
model.setCost(cost);
model.setValue(value);
model.setExpand(command.getExpand());
model.setValue(new ObjectVO(value, command.getExpand()));
model.setSizeLimit(command.getSizeLimit());
model.setClassName(advice.getClazz().getName());
model.setMethodName(advice.getMethod().getName());

@ -22,11 +22,10 @@ public class GetStaticView extends ResultView<GetStaticModel> {
process.write("\n");
return;
}
int expand = result.getExpand();
if (result.getField() != null) {
ObjectVO field = result.getField();
String valueStr = StringUtils.objectToString(expand >= 0 ? new ObjectView(field.getValue(), expand).draw() : field.getValue());
process.write("field: " + field.getName() + "\n" + valueStr + "\n");
String valueStr = StringUtils.objectToString(field.needExpand() ? new ObjectView(field).draw() : field.getObject());
process.write("field: " + result.getFieldName() + "\n" + valueStr + "\n");
} else if (result.getMatchedClasses() != null) {
Element table = ClassUtils.renderMatchedClasses(result.getMatchedClasses());
process.write(RenderUtil.render(table)).write("\n");

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.OgnlModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.StringUtils;
@ -19,9 +20,8 @@ public class OgnlView extends ResultView<OgnlModel> {
return;
}
int expand = model.getExpand();
Object value = model.getValue();
String resultStr = StringUtils.objectToString(expand >= 0 ? new ObjectView(value, expand).draw() : value);
ObjectVO objectVO = model.getValue();
String resultStr = StringUtils.objectToString(objectVO.needExpand() ? new ObjectView(objectVO).draw() : objectVO.getObject());
process.write(resultStr).write("\n");
}
}

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.FieldVO;
import com.taobao.arthas.core.command.model.SearchClassModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.ClassUtils;
@ -20,7 +21,7 @@ public class SearchClassView extends ResultView<SearchClassModel> {
if (result.isDetailed()) {
process.write(RenderUtil.render(ClassUtils.renderClassInfo(result.getClassInfo(),
result.isWithField(), result.getExpand()), process.width()));
result.isWithField()), process.width()));
process.write("\n");
} else if (result.getClassNames() != null) {
for (String className : result.getClassNames()) {

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.TimeFragmentVO;
import com.taobao.arthas.core.command.model.TimeTunnelModel;
import com.taobao.arthas.core.command.monitor200.TimeTunnelTable;
@ -21,8 +22,6 @@ public class TimeTunnelView extends ResultView<TimeTunnelModel> {
@Override
public void draw(CommandProcess process, TimeTunnelModel timeTunnelModel) {
Integer expand = timeTunnelModel.getExpand();
boolean isNeedExpand = isNeedExpand(expand);
Integer sizeLimit = timeTunnelModel.getSizeLimit();
if (timeTunnelModel.getTimeFragmentList() != null) {
@ -35,25 +34,25 @@ public class TimeTunnelView extends ResultView<TimeTunnelModel> {
TimeFragmentVO tf = timeTunnelModel.getTimeFragment();
TableElement table = TimeTunnelTable.createDefaultTable();
TimeTunnelTable.drawTimeTunnel(table, tf);
TimeTunnelTable.drawParameters(table, tf.getParams(), isNeedExpand, expand);
TimeTunnelTable.drawReturnObj(table, tf, isNeedExpand, expand, sizeLimit);
TimeTunnelTable.drawThrowException(table, tf, isNeedExpand, expand);
TimeTunnelTable.drawParameters(table, tf.getParams());
TimeTunnelTable.drawReturnObj(table, tf, sizeLimit);
TimeTunnelTable.drawThrowException(table, tf);
process.write(RenderUtil.render(table, process.width()));
} else if (timeTunnelModel.getWatchValue() != null) {
//watch single TimeFragment: tt -i 1000 -w 'params'
Object value = timeTunnelModel.getWatchValue();
if (isNeedExpand) {
process.write(new ObjectView(value, expand, sizeLimit).draw()).write("\n");
ObjectVO valueVO = timeTunnelModel.getWatchValue();
if (valueVO.needExpand()) {
process.write(new ObjectView(sizeLimit, valueVO).draw()).write("\n");
} else {
process.write(StringUtils.objectToString(value)).write("\n");
process.write(StringUtils.objectToString(valueVO.getObject())).write("\n");
}
} else if (timeTunnelModel.getWatchResults() != null) {
//search & watch: tt -s 'returnObj!=null' -w 'returnObj'
TableElement table = TimeTunnelTable.createDefaultTable();
TimeTunnelTable.drawWatchTableHeader(table);
TimeTunnelTable.drawWatchResults(table, timeTunnelModel.getWatchResults(), isNeedExpand, expand, sizeLimit);
TimeTunnelTable.drawWatchResults(table, timeTunnelModel.getWatchResults(), sizeLimit);
process.write(RenderUtil.render(table, process.width()));
} else if (timeTunnelModel.getReplayResult() != null) {
@ -62,11 +61,11 @@ public class TimeTunnelView extends ResultView<TimeTunnelModel> {
Integer replayNo = timeTunnelModel.getReplayNo();
TableElement table = TimeTunnelTable.createDefaultTable();
TimeTunnelTable.drawPlayHeader(replayResult.getClassName(), replayResult.getMethodName(), replayResult.getObject(), replayResult.getIndex(), table);
TimeTunnelTable.drawParameters(table, replayResult.getParams(), isNeedExpand, expand);
TimeTunnelTable.drawParameters(table, replayResult.getParams());
if (replayResult.isReturn()) {
TimeTunnelTable.drawPlayResult(table, replayResult.getReturnObj(), isNeedExpand, expand, sizeLimit, replayResult.getCost());
TimeTunnelTable.drawPlayResult(table, replayResult.getReturnObj(), sizeLimit, replayResult.getCost());
} else {
TimeTunnelTable.drawPlayException(table, replayResult.getThrowExp(), isNeedExpand, expand);
TimeTunnelTable.drawPlayException(table, replayResult.getThrowExp());
}
process.write(RenderUtil.render(table, process.width()))
.write(format("Time fragment[%d] successfully replayed %d times.", replayResult.getIndex(), replayNo))
@ -74,8 +73,4 @@ public class TimeTunnelView extends ResultView<TimeTunnelModel> {
}
}
private boolean isNeedExpand(Integer expand) {
return null != expand && expand > 0;
}
}

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.VmToolModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.StringUtils;
@ -20,9 +21,8 @@ public class VmToolView extends ResultView<VmToolModel> {
return;
}
int expand = model.getExpand();
Object value = model.getValue();
String resultStr = StringUtils.objectToString(expand >= 0 ? new ObjectView(value, expand).draw() : value);
ObjectVO objectVO = model.getValue();
String resultStr = StringUtils.objectToString(objectVO.needExpand() ? new ObjectView(objectVO).draw() : objectVO.getObject());
process.write(resultStr).write("\n");
}
}

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command.view;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.command.model.WatchModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.util.DateUtils;
@ -15,15 +16,10 @@ public class WatchView extends ResultView<WatchModel> {
@Override
public void draw(CommandProcess process, WatchModel model) {
Object value = model.getValue();
ObjectVO objectVO = model.getValue();
String result = StringUtils.objectToString(
isNeedExpand(model) ? new ObjectView(value, model.getExpand(), model.getSizeLimit()).draw() : value);
objectVO.needExpand() ? new ObjectView(model.getSizeLimit(), objectVO).draw() : objectVO.getObject());
process.write("method=" + model.getClassName() + "." + model.getMethodName() + " location=" + model.getAccessPoint() + "\n");
process.write("ts=" + DateUtils.formatDate(model.getTs()) + "; [cost=" + model.getCost() + "ms] result=" + result + "\n");
}
private boolean isNeedExpand(WatchModel model) {
Integer expand = model.getExpand();
return null != expand && expand >= 0;
}
}

@ -3,6 +3,10 @@ package com.taobao.arthas.core.shell.term.impl.http.api;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.util.IOUtils;
import com.taobao.arthas.common.ArthasConstants;
import com.taobao.arthas.common.PidUtils;
import com.taobao.arthas.core.command.model.*;
@ -56,6 +60,7 @@ import java.util.concurrent.TimeUnit;
public class HttpApiHandler {
private static final Logger logger = LoggerFactory.getLogger(HttpApiHandler.class);
private static final ValueFilter[] JSON_FILTERS = new ValueFilter[] { new ObjectVOFilter() };
private static final String ONETIME_SESSION_KEY = "oneTimeSession";
public static final int DEFAULT_EXEC_TIMEOUT = 30000;
private final SessionManager sessionManager;
@ -174,7 +179,7 @@ public class HttpApiHandler {
private void writeResult(DefaultFullHttpResponse response, Object result) throws IOException {
ByteBufOutputStream out = new ByteBufOutputStream(response.content());
try {
JSON.writeJSONString(out, result);
JSON.writeJSONString(out, IOUtils.UTF8, result, SerializeConfig.globalInstance, JSON_FILTERS, null, JSON.DEFAULT_GENERATE_FEATURE);
} catch (IOException e) {
logger.error("write json to response failed", e);
throw e;

@ -0,0 +1,25 @@
package com.taobao.arthas.core.shell.term.impl.http.api;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.util.StringUtils;
import com.taobao.arthas.core.view.ObjectView;
/**
* @author hengyunabc 2022-08-24
*
*/
public class ObjectVOFilter implements ValueFilter {
@Override
public Object process(Object object, String name, Object value) {
if (value instanceof ObjectVO) {
ObjectVO vo = (ObjectVO) value;
String resultStr = StringUtils.objectToString(vo.needExpand() ? new ObjectView(vo).draw() : value);
return resultStr;
}
return value;
}
}

@ -42,10 +42,10 @@ public class ClassUtils {
}
public static Element renderClassInfo(ClassDetailVO clazz) {
return renderClassInfo(clazz, false, null);
return renderClassInfo(clazz, false);
}
public static Element renderClassInfo(ClassDetailVO clazz, boolean isPrintField, Integer expand) {
public static Element renderClassInfo(ClassDetailVO clazz, boolean isPrintField) {
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
table.row(label("class-info").style(Decoration.bold.bold()), label(clazz.getClassInfo()))
@ -69,12 +69,12 @@ public class ClassUtils {
.row(label("classLoaderHash").style(Decoration.bold.bold()), label(clazz.getClassLoaderHash()));
if (isPrintField) {
table.row(label("fields").style(Decoration.bold.bold()), TypeRenderUtils.drawField(clazz, expand));
table.row(label("fields").style(Decoration.bold.bold()), TypeRenderUtils.drawField(clazz));
}
return table;
}
public static ClassDetailVO createClassInfo(Class clazz, boolean withFields) {
public static ClassDetailVO createClassInfo(Class clazz, boolean withFields, Integer expand) {
CodeSource cs = clazz.getProtectionDomain().getCodeSource();
ClassDetailVO classInfo = new ClassDetailVO();
classInfo.setName(StringUtils.classname(clazz));
@ -97,7 +97,7 @@ public class ClassUtils {
classInfo.setClassloader(TypeRenderUtils.getClassloader(clazz));
classInfo.setClassLoaderHash(StringUtils.classLoaderHash(clazz));
if (withFields) {
classInfo.setFields(TypeRenderUtils.getFields(clazz));
classInfo.setFields(TypeRenderUtils.getFields(clazz, expand));
}
return classInfo;
}

@ -3,6 +3,7 @@ package com.taobao.arthas.core.util;
import com.taobao.arthas.core.command.model.ClassDetailVO;
import com.taobao.arthas.core.command.model.ClassVO;
import com.taobao.arthas.core.command.model.FieldVO;
import com.taobao.arthas.core.command.model.ObjectVO;
import com.taobao.arthas.core.view.ObjectView;
import com.taobao.text.ui.Element;
import com.taobao.text.ui.TableElement;
@ -75,7 +76,7 @@ public class TypeRenderUtils {
return root;
}
public static Element drawField(ClassDetailVO clazz, Integer expand) {
public static Element drawField(ClassDetailVO clazz) {
TableElement fieldsTable = new TableElement(1).leftCellPadding(0).rightCellPadding(0);
FieldVO[] fields = clazz.getFields();
if (fields == null || fields.length == 0) {
@ -94,7 +95,8 @@ public class TypeRenderUtils {
}
if (field.isStatic()) {
Object o = (expand != null && expand >= 0) ? new ObjectView(field.getValue(), expand).draw() : field.getValue();
ObjectVO objectVO = field.getValue();
Object o = objectVO.needExpand() ? new ObjectView(objectVO).draw() : objectVO.getObject();
fieldTable.row("value", StringUtils.objectToString(o));
}
@ -160,7 +162,7 @@ public class TypeRenderUtils {
return list.toArray(new String[0]);
}
public static FieldVO[] getFields(Class clazz) {
public static FieldVO[] getFields(Class clazz, Integer expand) {
Field[] fields = clazz.getDeclaredFields();
if (fields.length == 0) {
return new FieldVO[0];
@ -175,7 +177,7 @@ public class TypeRenderUtils {
fieldVO.setAnnotations(getAnnotations(field.getAnnotations()));
if (Modifier.isStatic(field.getModifiers())) {
fieldVO.setStatic(true);
fieldVO.setValue(getFieldValue(field));
fieldVO.setValue(new ObjectVO(getFieldValue(field), expand));
} else {
fieldVO.setStatic(false);
}

@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.taobao.arthas.common.ArthasConstants;
import com.taobao.arthas.core.GlobalOptions;
import com.taobao.arthas.core.command.model.ObjectVO;
import java.io.PrintWriter;
import java.io.StringWriter;
@ -29,6 +30,15 @@ public class ObjectView implements View {
private final int deep;
private final int maxObjectLength;
public ObjectView(ObjectVO objectVO) {
this(MAX_OBJECT_LENGTH, objectVO);
}
// int参数在前面防止构造函数二义性
public ObjectView(int maxObjectLength, ObjectVO objectVO) {
this(objectVO.getObject(), objectVO.expandOrDefault(), maxObjectLength);
}
public ObjectView(Object object, int deep) {
this(object, deep, MAX_OBJECT_LENGTH);
}

Loading…
Cancel
Save