mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
HTTP API support plain txt ObjectView #2261
This commit is contained in:
@@ -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,6 +34,14 @@ public class GetStaticModel extends ResultModel {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public Collection<ClassVO> getMatchedClasses() {
|
||||
return matchedClasses;
|
||||
}
|
||||
@@ -42,14 +50,6 @@ public class GetStaticModel extends ResultModel {
|
||||
this.matchedClasses = matchedClasses;
|
||||
}
|
||||
|
||||
public int getExpand() {
|
||||
return expand;
|
||||
}
|
||||
|
||||
public void setExpand(int expand) {
|
||||
this.expand = expand;
|
||||
}
|
||||
|
||||
public String getClassLoaderClass() {
|
||||
return classLoaderClass;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+17
-13
@@ -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();
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -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;
|
||||
|
||||
+25
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user