package com.github.ompc.greys.core.textui.ext; import com.github.ompc.greys.core.Advice; import com.github.ompc.greys.core.GlobalOptions; import com.github.ompc.greys.core.TimeFragment; import com.github.ompc.greys.core.textui.TComponent; import com.github.ompc.greys.core.textui.TTable; import com.github.ompc.greys.core.textui.TTable.ColumnDefine; import com.github.ompc.greys.core.util.GaStringUtils; import com.github.ompc.greys.core.util.SimpleDateFormatHolder; import com.github.ompc.greys.core.util.SizeOf; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.instrument.Instrumentation; import static com.github.ompc.greys.core.textui.TTable.Align.LEFT; import static com.github.ompc.greys.core.textui.TTable.Align.RIGHT; /** * 时间碎片详情展示 * Created by oldmanpushcart@gmail.com on 15/10/3. */ public class TTimeFragmentDetail implements TComponent { private final Instrumentation inst; private final TimeFragment timeFragment; private final Integer expend; public TTimeFragmentDetail(final Instrumentation inst, final TimeFragment timeFragment, final Integer expend) { this.inst = inst; this.timeFragment = timeFragment; this.expend = expend; } /** * 是否需要展开输出对象 */ private boolean isNeedExpend() { return null != expend && expend > 0; } @Override public String rendering() { final Advice advice = timeFragment.advice; final String className = advice.getClazz().getName(); final String methodName = advice.getMethod().getName(); final TTable tTable = new TTable( new ColumnDefine[]{ new ColumnDefine(15, false, RIGHT), new ColumnDefine(150, false, LEFT) }) .padding(1) .addRow("INDEX", timeFragment.id) .addRow("PROCESS-ID", timeFragment.processId) .addRow("GMT-CREATE", SimpleDateFormatHolder.getInstance().format(timeFragment.gmtCreate)) .addRow("COST(ms)", timeFragment.cost) .addRow("OBJECT", GaStringUtils.hashCodeToHexString(advice.target)) .addRow("CLASS", className) .addRow("METHOD", methodName) .addRow("IS-RETURN", advice.isReturn) .addRow("IS-EXCEPTION", advice.isThrow); if (advice.isTraceSupport()) { tTable.addRow("TRACE-ID", advice.getTraceId()); } // fill the parameters if (null != advice.params) { int paramIndex = 0; for (Object param : advice.params) { final StringBuilder titleSB = new StringBuilder("PARAMETERS[" + paramIndex++ + "]"); if (GlobalOptions.isDisplayObjectSize) { titleSB.append("\n").append(new SizeOf(inst, param, SizeOf.HeapType.SHALLOW)); titleSB.append("\n").append(new SizeOf(inst, param, SizeOf.HeapType.RETAINED)); } tTable.addRow(titleSB.toString(), new TObject(param, expend).rendering()); } } // fill the returnObj if (!advice.isThrow) { final StringBuilder titleSB = new StringBuilder("RETURN-OBJ"); if (GlobalOptions.isDisplayObjectSize) { titleSB.append("\n").append(new SizeOf(inst, advice.returnObj, SizeOf.HeapType.SHALLOW)); titleSB.append("\n").append(new SizeOf(inst, advice.returnObj, SizeOf.HeapType.RETAINED)); } tTable.addRow( titleSB.toString(), new TObject(advice.returnObj, expend).rendering() ); } // fill the throw exception if (advice.isThrow) { //noinspection ThrowableResultOfMethodCallIgnored final Throwable throwable = advice.throwExp; final StringBuilder titleSB = new StringBuilder("THROW-EXCEPTION"); if (GlobalOptions.isDisplayObjectSize) { titleSB.append("\n").append(new SizeOf(inst, advice.throwExp, SizeOf.HeapType.SHALLOW)); titleSB.append("\n").append(new SizeOf(inst, advice.throwExp, SizeOf.HeapType.RETAINED)); } if (isNeedExpend()) { tTable.addRow(titleSB.toString(), new TObject(advice.throwExp, expend).rendering()); } else { final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter); try { throwable.printStackTrace(printWriter); tTable.addRow(titleSB.toString(), stringWriter.toString()); } finally { printWriter.close(); } } } // fill the stack tTable.addRow("STACK", timeFragment.stack); return tTable.rendering(); } }