diff --git a/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java b/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java index 689bc565b..2698f74d8 100644 --- a/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java +++ b/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java @@ -17,6 +17,7 @@ import com.nhn.hippo.web.calltree.span.SpanAlign; import com.nhn.hippo.web.service.FlowChartService; import com.nhn.hippo.web.service.SpanService; import com.nhn.hippo.web.vo.TraceId; +import com.nhn.hippo.web.vo.callstacks.RecordSet; /** * @@ -35,18 +36,25 @@ public class BusinessTransactionController { @RequestMapping(value = "/selectTransaction", method = RequestMethod.GET) public ModelAndView flow(@RequestParam(value = "traceId") String traceId) { logger.debug("traceId:{}", traceId); + + // select spans List spanAligns = spanService.selectSpan(traceId); ModelAndView mv = new ModelAndView("selectTransaction"); mv.addObject("spanList", spanAligns); mv.addObject("traceId", traceId); -// Set traceIds = new HashSet(1); -// traceIds.add(new TraceId(UUID.fromString(traceId))); + // call tree ServerCallTree callTree = flow.selectServerCallTree(new TraceId(UUID.fromString(traceId))); mv.addObject("nodes", callTree.getNodes()); mv.addObject("links", callTree.getLinks()); - + + // call stacks + RecordSet recordset = new RecordSet(spanAligns); + mv.addObject("callstack", recordset.getIterator()); + mv.addObject("callstackStart", recordset.getStartTime()); + mv.addObject("callstackEnd", recordset.getEndTime()); + return mv; } } diff --git a/src/main/java/com/nhn/hippo/web/utils/AnnotationUtils.java b/src/main/java/com/nhn/hippo/web/utils/AnnotationUtils.java index a567831f7..51947a926 100644 --- a/src/main/java/com/nhn/hippo/web/utils/AnnotationUtils.java +++ b/src/main/java/com/nhn/hippo/web/utils/AnnotationUtils.java @@ -7,6 +7,7 @@ import java.util.Date; import java.util.List; import java.util.UUID; +import com.profiler.common.AnnotationNames; import com.profiler.common.ServiceType; import com.profiler.common.bo.AnnotationBo; import com.profiler.common.bo.Span; @@ -15,10 +16,6 @@ public class AnnotationUtils { private static final String FORMAT = "yyyy-MM-dd HH:mm:ss SSS"; - private static final String API = "API"; - private static final String ARCUS_COMMAND = "arcus.command"; - private static final String HTTP_URL = "http.url"; - @Deprecated public static String longToDateStr(long date) { SimpleDateFormat format = new SimpleDateFormat(FORMAT); @@ -43,7 +40,7 @@ public class AnnotationUtils { public static Object getDisplayMethod(Span span) { List list = span.getAnnotationBoList(); - int index = Collections.binarySearch(list, API); + int index = Collections.binarySearch(list, AnnotationNames.API); if (index > -1) { return list.get(index).getValue(); @@ -60,15 +57,19 @@ public class AnnotationUtils { List list = span.getAnnotationBoList(); int index = -1; if (span.getServiceType() == ServiceType.ARCUS || span.getServiceType() == ServiceType.MEMCACHED) { - index = Collections.binarySearch(list, ARCUS_COMMAND); + index = Collections.binarySearch(list, AnnotationNames.ARCUS_COMMAND); } if (span.getServiceType() == ServiceType.HTTP_CLIENT) { - index = Collections.binarySearch(list, HTTP_URL); + index = Collections.binarySearch(list, AnnotationNames.HTTP_URL); } if (span.getServiceType() == ServiceType.TOMCAT) { - index = Collections.binarySearch(list, HTTP_URL); + index = Collections.binarySearch(list, AnnotationNames.HTTP_URL); + } + + if (span.getServiceType() == ServiceType.MYSQL) { + index = Collections.binarySearch(list, AnnotationNames.ARGS0); } if (index > -1) { diff --git a/src/main/java/com/nhn/hippo/web/vo/callstacks/Record.java b/src/main/java/com/nhn/hippo/web/vo/callstacks/Record.java new file mode 100644 index 000000000..a9ebaebca --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/vo/callstacks/Record.java @@ -0,0 +1,68 @@ +package com.nhn.hippo.web.vo.callstacks; + +/** + * each stack + * + * @author netspider + * + */ +public class Record { + private final int tab; + private final boolean method; + + private final String title; + private final String arguments; + private final long begin; + private final long elapsed; + private final String agent; + private final String service; + + public Record(int tab, boolean method, String title, String arguments, long begin, long elapsed, String agent, String service) { + this.tab = tab; + this.method = method; + + this.title = title; + this.arguments = arguments; + this.begin = begin; + this.elapsed = elapsed; + this.agent = agent; + this.service = service; + } + + public int getTab() { + return tab; + } + + public boolean isMethod() { + return method; + } + + public String getTitle() { + return title; + } + + public String getArguments() { + return arguments; + } + + public long getBegin() { + return begin; + } + + public long getElapsed() { + return elapsed; + } + + public String getAgent() { + return agent; + } + + public String getService() { + return service; + } + + @Override + public String toString() { + return "Record [tab=" + tab + ", method=" + method + ", title=" + title + ", arguments=" + arguments + ", begin=" + begin + ", elapsed=" + elapsed + ", agent=" + agent + ", service=" + service + "]"; + } +} diff --git a/src/main/java/com/nhn/hippo/web/vo/callstacks/RecordSet.java b/src/main/java/com/nhn/hippo/web/vo/callstacks/RecordSet.java new file mode 100644 index 000000000..74b78fa27 --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/vo/callstacks/RecordSet.java @@ -0,0 +1,114 @@ +package com.nhn.hippo.web.vo.callstacks; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.nhn.hippo.web.calltree.span.SpanAlign; +import com.nhn.hippo.web.utils.AnnotationUtils; +import com.profiler.common.AnnotationNames; +import com.profiler.common.bo.AnnotationBo; +import com.profiler.common.bo.SpanBo; +import com.profiler.common.bo.SubSpanBo; + +/** + * + * @author netspider + * + */ +public class RecordSet { + private long startTime = -1; + private long endTime = -1; + + private final List recordset; + + public RecordSet(List spanAligns) { + recordset = new ArrayList(); + addSpanRecord(spanAligns); + } + + public Iterator getIterator() { + return recordset.iterator(); + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public boolean isStartTimeSet() { + return startTime != -1; + } + + public boolean isEndTimeSet() { + return endTime != -1; + } + + private void addAnnotationRecord(int depth, List annotationBoList) { + for (AnnotationBo ann : annotationBoList) { + String annKey = ann.getKey(); + if (AnnotationNames.API.equals(annKey) || AnnotationNames.API_ID.equals(annKey)) + continue; + + if (AnnotationNames.EXCEPTION.equals(annKey)) { + recordset.add(new Record(depth, false, ann.getValue().toString(), null, 0L, 0L, null, null)); + } else if (AnnotationNames.BINDVALUE.equals(annKey)) { + recordset.add(new Record(depth, false, ann.getKey(), ann.getValue().toString(), 0L, 0L, null, null)); + } else if (AnnotationNames.PREPAREDSTATEMENT.equals(annKey)) { + recordset.add(new Record(depth, false, ann.getKey(), ann.getValue().toString(), 0L, 0L, null, null)); + } + } + } + + private void addSpanRecord(List spanAligns) { + boolean marked = false; + + for (SpanAlign sa : spanAligns) { + if (sa.isRoot()) { + SpanBo span = sa.getSpan(); + AnnotationUtils.sortAnnotationListByKey(span); + String method = (String) AnnotationUtils.getDisplayMethod(span); + String arguments = (String) AnnotationUtils.getDisplayArgument(span); + + long begin = span.getStartTime(); + long elapsed = span.getElapsed(); + + if (!marked) { + setStartTime(begin); + setEndTime(begin + elapsed); + } + + recordset.add(new Record(sa.getDepth(), true, method, arguments, begin, elapsed, span.getAgentId(), span.getServiceName())); + addAnnotationRecord(sa.getDepth() + 1, span.getAnnotationBoList()); + } else { + SubSpanBo subSpan = sa.getSubSpanBo(); + + AnnotationUtils.sortAnnotationListByKey(subSpan); + String method = (String) AnnotationUtils.getDisplayMethod(subSpan); + Object arguments = AnnotationUtils.getDisplayArgument(subSpan); + + long begin = sa.getSpan().getStartTime() + subSpan.getStartElapsed(); + long elapsed = subSpan.getEndElapsed(); + + if (!marked) { + setStartTime(begin); + setEndTime(begin + elapsed); + } + + recordset.add(new Record(sa.getDepth(), true, method, (arguments != null) ? arguments.toString() : "", begin, elapsed, subSpan.getAgentId(), subSpan.getServiceName())); + addAnnotationRecord(sa.getDepth() + 1, subSpan.getAnnotationBoList()); + } + } + } +} diff --git a/src/main/resources/hbase.properties b/src/main/resources/hbase.properties index 67ebd6fdf..afe589a66 100644 --- a/src/main/resources/hbase.properties +++ b/src/main/resources/hbase.properties @@ -1,4 +1,4 @@ -#hbase.client.host=localhost +hbase.client.host=localhost #hbase.client.host=10.101.17.108 #dev-hippo002.ncl @@ -6,7 +6,7 @@ #3대 짜리 #hbase.client.host=10.25.131.38 -hbase.client.host=dev-hippo002.ncl +#hbase.client.host=dev-hippo002.ncl hbase.client.port=2181 hbase.htable.threads.max=128 \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/selectTransaction.jsp b/src/main/webapp/WEB-INF/views/selectTransaction.jsp index a2cb0437b..8c29b1598 100644 --- a/src/main/webapp/WEB-INF/views/selectTransaction.jsp +++ b/src/main/webapp/WEB-INF/views/selectTransaction.jsp @@ -42,8 +42,14 @@ }