diff --git a/src/main/java/com/nhn/hippo/web/controller/ApplicationMapController.java b/src/main/java/com/nhn/hippo/web/controller/ApplicationMapController.java index efe578664..b4eaf2ac6 100644 --- a/src/main/java/com/nhn/hippo/web/controller/ApplicationMapController.java +++ b/src/main/java/com/nhn/hippo/web/controller/ApplicationMapController.java @@ -1,24 +1,16 @@ package com.nhn.hippo.web.controller; -import java.util.Set; - import javax.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.util.StopWatch; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.nhn.hippo.web.applicationmap.ApplicationMap; -import com.nhn.hippo.web.calltree.server.ServerCallTree; import com.nhn.hippo.web.service.ApplicationMapService; -import com.nhn.hippo.web.service.FlowChartService; -import com.nhn.hippo.web.vo.TraceId; /** * @@ -26,12 +18,7 @@ import com.nhn.hippo.web.vo.TraceId; */ @Controller public class ApplicationMapController extends BaseController { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private FlowChartService flow; - + @Autowired private ApplicationMapService applicationMapService; @@ -52,64 +39,4 @@ public class ApplicationMapController extends BaseController { long from = to - period; return getServerMapData2(model, response, applicationName, serviceType, from, to); } - - @RequestMapping(value = "/getServerMapData", method = RequestMethod.GET) - public String getServerMapData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to) { - // TODO 제거 하거나, interceptor로 할것. - StopWatch watch = new StopWatch(); - watch.start("scanTraceindex"); - - Set traceIdList = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, from, to); - - watch.stop(); - logger.info("Fetch traceIdList elapsed : {}ms, {} traces", watch.getLastTaskTimeMillis(), traceIdList.size()); - watch.start("selectServerCallTree"); - - ServerCallTree callTree = flow.selectServerCallTree(traceIdList, applicationName, from, to); - - watch.stop(); - logger.info("Fetch calltree time : {}ms", watch.getLastTaskTimeMillis()); - - model.addAttribute("nodes", callTree.getNodes()); - model.addAttribute("links", callTree.getLinks()); - - addResponseHeader(response); - - return "servermap"; - } - - @RequestMapping(value = "/getLastServerMapData", method = RequestMethod.GET) - public String getLastServerMapData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("period") long period) { - long to = getQueryEndTime(); - long from = to - period; - return getServerMapData(model, response, applicationName, from, to); - } - - @Deprecated - @RequestMapping(value = "/flowserverByHost", method = RequestMethod.GET) - public String flowServerByHost(Model model, @RequestParam("host") String[] hosts, @RequestParam("from") long from, @RequestParam("to") long to) { - String[] agentIds = flow.selectAgentIds(hosts); - - // TODO 제거 하거나, interceptor로 할것. - StopWatch watch = new StopWatch(); - watch.start("scanTraceindex"); - - Set traceIds = flow.selectTraceIdsFromTraceIndex(agentIds, from, to); - - watch.stop(); - logger.info("time:{} {}", watch.getLastTaskTimeMillis(), traceIds.size()); - watch.start("selectServerCallTree"); - - ServerCallTree callTree = flow.selectServerCallTree(traceIds); - - watch.stop(); - logger.info("time:{}", watch.getLastTaskTimeMillis()); - - model.addAttribute("nodes", callTree.getNodes()); - model.addAttribute("links", callTree.getLinks()); - - logger.debug("callTree:{}", callTree); - - return "flowserver"; - } } \ No newline at end of file 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 7ac42db2d..0d12179b5 100644 --- a/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java +++ b/src/main/java/com/nhn/hippo/web/controller/BusinessTransactionController.java @@ -80,13 +80,20 @@ public class BusinessTransactionController extends BaseController { return getBusinessTransactionsData(model, response, applicationName, from, to); } - @RequestMapping(value = "/selectTransaction", method = RequestMethod.GET) - public ModelAndView selectTransaction(@RequestParam("traceId") String traceIdParam, @RequestParam("focusTimestamp") long focusTimestamp) { + /** + * 선택한 하나의 Transaction 정보 조회. + * + * @param traceIdParam + * @param focusTimestamp + * @return + */ + @RequestMapping(value = "/transactionInfo", method = RequestMethod.GET) + public ModelAndView transactionInfo(@RequestParam("traceId") String traceIdParam, @RequestParam("focusTimestamp") long focusTimestamp) { logger.debug("traceId:{}", traceIdParam); final TraceId traceId = new TraceId(traceIdParam); - ModelAndView mv = new ModelAndView("selectTransaction"); + ModelAndView mv = new ModelAndView("transactionInfo"); try { // select spans diff --git a/src/main/java/com/nhn/hippo/web/controller/ScatterChartController.java b/src/main/java/com/nhn/hippo/web/controller/ScatterChartController.java index fbf210444..eba7c2157 100644 --- a/src/main/java/com/nhn/hippo/web/controller/ScatterChartController.java +++ b/src/main/java/com/nhn/hippo/web/controller/ScatterChartController.java @@ -15,9 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; -import com.nhn.hippo.web.service.FlowChartService; -import com.nhn.hippo.web.service.SpanService; -import com.nhn.hippo.web.vo.RequestMetadataQuery; +import com.nhn.hippo.web.service.ScatterChartService; +import com.nhn.hippo.web.vo.TransactionMetadataQuery; import com.nhn.hippo.web.vo.scatter.Dot; import com.profiler.common.bo.SpanBo; @@ -31,10 +30,7 @@ public class ScatterChartController extends BaseController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired - private FlowChartService flow; - - @Autowired - private SpanService spanService; + private ScatterChartService scatter; @RequestMapping(value = "/scatterpopup", method = RequestMethod.GET) public String scatterPopup(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to, @RequestParam("period") long period, @RequestParam("usePeriod") boolean usePeriod) { @@ -45,29 +41,6 @@ public class ScatterChartController extends BaseController { model.addAttribute("usePeriod", usePeriod); return "scatterPopup"; } - - @RequestMapping(value = "/scatterView", method = RequestMethod.GET) - public String getScatterView(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to, @RequestParam("limit") int limit) { - StopWatch watch = new StopWatch(); - watch.start("selectScatterData"); - - List scatterData = flow.selectScatterData(applicationName, from, to, limit); - watch.stop(); - - logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); - - model.addAttribute("scatter", scatterData); - - addResponseHeader(response); - return "scatter_view"; - } - - @RequestMapping(value = "/lastScatterView", method = RequestMethod.GET) - public String getLastScatterView(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("period") long period, @RequestParam("limit") int limit) { - long to = getQueryEndTime(); - long from = to - period; - return getScatterView(model, response, applicationName, from, to, limit); - } /** * @@ -82,11 +55,11 @@ public class ScatterChartController extends BaseController { * @return */ @RequestMapping(value = "/getScatterData", method = RequestMethod.GET) - public String getScatterData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to, @RequestParam("limit") int limit, @RequestParam(value="_callback", required=false) String jsonpCallback) { + public String getScatterData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to, @RequestParam("limit") int limit, @RequestParam(value = "_callback", required = false) String jsonpCallback) { StopWatch watch = new StopWatch(); watch.start("selectScatterData"); - List scatterData = flow.selectScatterData(applicationName, from, to, limit); + List scatterData = scatter.selectScatterData(applicationName, from, to, limit); watch.stop(); logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); @@ -94,7 +67,7 @@ public class ScatterChartController extends BaseController { model.addAttribute("scatter", scatterData); addResponseHeader(response); - + if (jsonpCallback == null) { return "scatter_json"; } else { @@ -114,7 +87,7 @@ public class ScatterChartController extends BaseController { * @return */ @RequestMapping(value = "/getLastScatterData", method = RequestMethod.GET) - public String getLastScatterData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("period") long period, @RequestParam("limit") int limit, @RequestParam(value="_callback", required=false) String jsonpCallback) { + public String getLastScatterData(Model model, HttpServletResponse response, @RequestParam("application") String applicationName, @RequestParam("period") long period, @RequestParam("limit") int limit, @RequestParam(value = "_callback", required = false) String jsonpCallback) { long to = getQueryEndTime(); long from = to - period; return getScatterData(model, response, applicationName, from, to, limit, jsonpCallback); @@ -139,7 +112,7 @@ public class ScatterChartController extends BaseController { long to = getQueryEndTime(); - List scatterData = flow.selectScatterData(applicationName, from, to, limit); + List scatterData = scatter.selectScatterData(applicationName, from, to, limit); watch.stop(); logger.info("Fetch scatterData time : {}ms", watch.getLastTaskTimeMillis()); @@ -167,13 +140,13 @@ public class ScatterChartController extends BaseController { * @param response * @return */ - @RequestMapping(value = "/requestmetadata", method = RequestMethod.POST) - public String requestmetadata(Model model, HttpServletRequest request, HttpServletResponse response) { + @RequestMapping(value = "/transactionmetadata", method = RequestMethod.POST) + public String transactionmetadata(Model model, HttpServletRequest request, HttpServletResponse response) { String TRACEID = "tr"; String TIME = "ti"; String RESPONSE_TIME = "re"; - RequestMetadataQuery query = new RequestMetadataQuery(); + TransactionMetadataQuery query = new TransactionMetadataQuery(); int index = 0; while (true) { @@ -190,11 +163,11 @@ public class ScatterChartController extends BaseController { } if (query.size() > 0) { - List metadata = spanService.selectRequestMetadata(query); + List metadata = scatter.selectTransactionMetadata(query); model.addAttribute("metadata", metadata); } addResponseHeader(response); - return "requestmetadata"; + return "transactionmetadata"; } } \ No newline at end of file diff --git a/src/main/java/com/nhn/hippo/web/dao/ClientStatisticsDao.java b/src/main/java/com/nhn/hippo/web/dao/ClientStatisticsDao.java deleted file mode 100644 index c7f69da8d..000000000 --- a/src/main/java/com/nhn/hippo/web/dao/ClientStatisticsDao.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.nhn.hippo.web.dao; - -import java.util.List; -import java.util.Map; - -import com.nhn.hippo.web.vo.ClientStatistics; - -/** - * - * @author netspider - * - */ -@Deprecated -public interface ClientStatisticsDao { - public List> selectClient(String applicationName, short serviceType, long from, long to); -} \ No newline at end of file diff --git a/src/main/java/com/nhn/hippo/web/dao/TerminalStatisticsDao.java b/src/main/java/com/nhn/hippo/web/dao/TerminalStatisticsDao.java deleted file mode 100644 index e60d3ef12..000000000 --- a/src/main/java/com/nhn/hippo/web/dao/TerminalStatisticsDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.nhn.hippo.web.dao; - -import java.util.List; -import java.util.Map; - -import com.nhn.hippo.web.vo.TerminalStatistics; - -/** - * - * @author netspider - * - */ -@Deprecated -public interface TerminalStatisticsDao { - /** - * - * @param applicationName - * @param from - * @param to - * @return key=applicationname - */ - public List> selectTerminal(String applicationName, long from, long to); -} diff --git a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCalleeDao.java b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCalleeDao.java index 977c98dd2..e3817f731 100644 --- a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCalleeDao.java +++ b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCalleeDao.java @@ -21,7 +21,6 @@ import com.profiler.common.hbase.HBaseTables; import com.profiler.common.hbase.HbaseOperations2; import com.profiler.common.util.ApplicationMapStatisticsUtils; import com.profiler.common.util.TimeSlot; -import com.profiler.common.util.TimeUtils; /** * diff --git a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCallerDao.java b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCallerDao.java index 0a9576ffc..cb420911d 100644 --- a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCallerDao.java +++ b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseApplicationMapStatisticsCallerDao.java @@ -21,7 +21,6 @@ import com.profiler.common.hbase.HBaseTables; import com.profiler.common.hbase.HbaseOperations2; import com.profiler.common.util.ApplicationMapStatisticsUtils; import com.profiler.common.util.TimeSlot; -import com.profiler.common.util.TimeUtils; /** * diff --git a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseClientStatisticsDao.java b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseClientStatisticsDao.java deleted file mode 100644 index 903180e97..000000000 --- a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseClientStatisticsDao.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.nhn.hippo.web.dao.hbase; - -import java.sql.Date; -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.Map; - -import org.apache.hadoop.hbase.client.Scan; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.hippo.web.dao.ClientStatisticsDao; -import com.nhn.hippo.web.vo.ClientStatistics; -import com.profiler.common.hbase.HBaseTables; -import com.profiler.common.hbase.HbaseOperations2; -import com.profiler.common.util.ClientStatUtils; -import com.profiler.common.util.TimeSlot; - -/** - * - * @author netspider - * - */ -@Deprecated -@Repository -public class HbaseClientStatisticsDao implements ClientStatisticsDao { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private int scanCacheSize = 40; - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("clientStatisticsMapper") - private RowMapper> clientStatisticsMapper; - - @Override - public List> selectClient(String applicationName, short serviceType, long from, long to) { - Scan scan = createScan(applicationName, serviceType, from, to); - return hbaseOperations2.find(HBaseTables.CLIENT_STATISTICS, scan, clientStatisticsMapper); - } - - private Scan createScan(String applicationName, short serviceType, long from, long to) { - long startTime = TimeSlot.getStatisticsRowSlot(from); - // hbase의 scanner를 사용하여 검색시 endTime은 검색 대상에 포함되지 않기 때문에, +1을 해줘야 된다. - long endTime = TimeSlot.getStatisticsRowSlot(to) + 1; - if (logger.isDebugEnabled()) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss,SSS"); - logger.debug("scan startTime:{} endTime:{}", simpleDateFormat.format(new Date(startTime)), simpleDateFormat.format(new Date(endTime))); - } - byte[] startKey = ClientStatUtils.makeRowKey(applicationName, serviceType, startTime); - byte[] endKey = ClientStatUtils.makeRowKey(applicationName, serviceType, endTime); - - Scan scan = new Scan(); - scan.setCaching(this.scanCacheSize); - scan.setStartRow(startKey); - scan.setStopRow(endKey); - scan.addFamily(HBaseTables.CLIENT_STATISTICS_CF_COUNTER); - scan.setId("clientStatisticsScan"); - - return scan; - } -} diff --git a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseTerminalStatisticsDao.java b/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseTerminalStatisticsDao.java deleted file mode 100644 index d46d3b68a..000000000 --- a/src/main/java/com/nhn/hippo/web/dao/hbase/HbaseTerminalStatisticsDao.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.nhn.hippo.web.dao.hbase; - -import java.sql.Date; -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.Map; - -import org.apache.hadoop.hbase.client.Scan; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Repository; - -import com.nhn.hippo.web.dao.TerminalStatisticsDao; -import com.nhn.hippo.web.vo.TerminalStatistics; -import com.profiler.common.hbase.HBaseTables; -import com.profiler.common.hbase.HbaseOperations2; -import com.profiler.common.util.TerminalSpanUtils; -import com.profiler.common.util.TimeSlot; - -/** - * - * @author netspider - * - */ -@Deprecated -@Repository -public class HbaseTerminalStatisticsDao implements TerminalStatisticsDao { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private int scanCacheSize = 40; - - @Autowired - private HbaseOperations2 hbaseOperations2; - - @Autowired - @Qualifier("terminalStatisticsMapper") - private RowMapper> terminalStatisticsMapper; - - @Override - public List> selectTerminal(String applicationName, long from, long to) { - Scan scan = createScan(applicationName, from, to); - return hbaseOperations2.find(HBaseTables.TERMINAL_STATISTICS, scan, terminalStatisticsMapper); - } - - private Scan createScan(String applicationName, long from, long to) { - long startTime = TimeSlot.getStatisticsRowSlot(from); - // hbase의 scanner를 사용하여 검색시 endTime은 검색 대상에 포함되지 않기 때문에, +1을 해줘야 된다. - long endTime = TimeSlot.getStatisticsRowSlot(to) + 1; - if (logger.isDebugEnabled()) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss,SSS"); - logger.debug("scan startTime:{} endTime:{}", simpleDateFormat.format(new Date(startTime)), simpleDateFormat.format(new Date(endTime))); - } - byte[] startKey = TerminalSpanUtils.makeRowKey(applicationName, startTime); - byte[] endKey = TerminalSpanUtils.makeRowKey(applicationName, endTime); - - Scan scan = new Scan(); - scan.setCaching(this.scanCacheSize); - scan.setStartRow(startKey); - scan.setStopRow(endKey); - scan.addFamily(HBaseTables.TERMINAL_STATISTICS_CF_COUNTER); - scan.setId("terminalStatisticsScan"); - - return scan; - } -} diff --git a/src/main/java/com/nhn/hippo/web/mapper/ClientStatisticsMapper.java b/src/main/java/com/nhn/hippo/web/mapper/ClientStatisticsMapper.java deleted file mode 100644 index a48c7a4a9..000000000 --- a/src/main/java/com/nhn/hippo/web/mapper/ClientStatisticsMapper.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.nhn.hippo.web.mapper; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.hippo.web.vo.ClientStatistics; -import com.profiler.common.hbase.HBaseTables; -import com.profiler.common.util.ClientStatUtils; - -/** - * - * @author netspider - * - */ -@Component -public class ClientStatisticsMapper implements RowMapper> { - - /** - *
-	 * rowkey = applicationName + serviceType + timeslot
-	 * cf = Count
-	 * cq = Slot
-	 * 
- */ - @Override - public Map mapRow(Result result, int rowNum) throws Exception { - KeyValue[] keyList = result.raw(); - - // key is destApplicationName. - Map stat = new HashMap(); - - for (KeyValue kv : keyList) { - if (kv.getFamilyLength() != HBaseTables.CLIENT_STATISTICS_CF_COUNTER.length) { - continue; - } - - byte[] qualifier = kv.getQualifier(); - - String destApplicationName = ClientStatUtils.getApplicationNameFromRowKey(kv.getRow()); - short destServiceType = ClientStatUtils.getApplicationServiceTypeFromRowKey(kv.getRow()); - long requestCount = Bytes.toLong(kv.getValue()); - short histogramSlot = ClientStatUtils.getHistogramSlotFromColumnName(qualifier); - boolean isError = histogramSlot == (short) -1; - - if (stat.containsKey(destApplicationName)) { - ClientStatistics statistics = stat.get(destApplicationName); - if (isError) { - statistics.getHistogram().incrErrorCount(requestCount); - } else { - statistics.getHistogram().addSample(histogramSlot, requestCount); - } - } else { - ClientStatistics statistics = new ClientStatistics(destApplicationName, destServiceType); - if (isError) { - statistics.getHistogram().incrErrorCount(requestCount); - } else { - statistics.getHistogram().addSample(histogramSlot, requestCount); - } - stat.put(destApplicationName, statistics); - } - } - - return stat; - } -} diff --git a/src/main/java/com/nhn/hippo/web/mapper/TerminalStatisticsMapper.java b/src/main/java/com/nhn/hippo/web/mapper/TerminalStatisticsMapper.java deleted file mode 100644 index 49219e7e4..000000000 --- a/src/main/java/com/nhn/hippo/web/mapper/TerminalStatisticsMapper.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.nhn.hippo.web.mapper; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.hadoop.hbase.KeyValue; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.data.hadoop.hbase.RowMapper; -import org.springframework.stereotype.Component; - -import com.nhn.hippo.web.vo.TerminalStatistics; -import com.profiler.common.hbase.HBaseTables; -import com.profiler.common.util.TerminalSpanUtils; - -/** - * - */ -@Component -public class TerminalStatisticsMapper implements RowMapper> { - - /** - *
-	 * rowkey = applicationName + timeslot
-	 * cf = Cnt, ErrCnt
-	 * cn = ServiceType + Slot + ApplicationName
-	 * 
-	 * output format
-	 * {
-	 * 	hippo={
-	 * 		From=TOMCAT11, To=hippo, ToSvcType=2101, Histogram={ "1000" : 3, "3000" : 0, "5000" : 0 }
-	 * 	},
-	 * 	dev={
-	 * 		From=TOMCAT11, To=dev, ToSvcType=8100, Histogram={ "100" : 1, "300" : 0, "500" : 0 }
-	 * 	},
-	 * 	MEMCACHED={
-	 * 		From=TOMCAT11, To=MEMCACHED, ToSvcType=8050, Histogram={ "100" : 1, "300" : 0, "500" : 0 }
-	 * 	},
-	 * 	section.cafe.naver.com={
-	 * 		From=TOMCAT11, To=section.cafe.naver.com, ToSvcType=9050, Histogram={ "1000" : 2, "3000" : 0, "5000" : 0 }
-	 * 	},
-	 * 	www.naver.com={
-	 * 		From=TOMCAT11, To=www.naver.com, ToSvcType=9050, Histogram={ "1000" : 2, "3000" : 0, "5000" : 0 }
-	 * 	}
-	 * }
-	 * 
-	 * 
- */ - @Override - public Map mapRow(Result result, int rowNum) throws Exception { - KeyValue[] keyList = result.raw(); - - // key is destApplicationName. - Map stat = new HashMap(); - - // key is destApplicationName - Map> destAppHostMap = new HashMap>(); - - for (KeyValue kv : keyList) { - if (kv.getFamilyLength() != HBaseTables.TERMINAL_STATISTICS_CF_COUNTER.length) { - continue; - } - - byte[] qualifier = kv.getQualifier(); - - String srcApplicationName = TerminalSpanUtils.getApplicationNameFromRowKey(kv.getRow()); - String destApplicationName = TerminalSpanUtils.getDestApplicationNameFromColumnName(qualifier); - long requestCount = Bytes.toLong(kv.getValue()); - short destServiceType = TerminalSpanUtils.getDestServiceTypeFromColumnName(qualifier); - short histogramSlot = TerminalSpanUtils.getHistogramSlotFromColumnName(qualifier); - String host = TerminalSpanUtils.getHost(qualifier); - boolean isError = histogramSlot == (short) -1; - - // hostname은 일단 따로 보관. - if (host != null) { - if (destAppHostMap.containsKey(destApplicationName)) { - destAppHostMap.get(destApplicationName).add(host); - } else { - Set set = new HashSet(); - set.add(host); - destAppHostMap.put(destApplicationName, set); - } - } - - if (stat.containsKey(destApplicationName)) { - TerminalStatistics statistics = stat.get(destApplicationName); - if (isError) { - statistics.getHistogram().incrErrorCount(requestCount); - } else { - statistics.getHistogram().addSample(histogramSlot, requestCount); - } - } else { - TerminalStatistics statistics = new TerminalStatistics(srcApplicationName, destApplicationName, destServiceType); - if (isError) { - statistics.getHistogram().incrErrorCount(requestCount); - } else { - statistics.getHistogram().addSample(histogramSlot, requestCount); - } - stat.put(destApplicationName, statistics); - } - } - - // statistics에 dest host정보 삽입. - for (Entry entry : stat.entrySet()) { - entry.getValue().addHosts(destAppHostMap.get(entry.getKey())); - } - - return stat; - } -} diff --git a/src/main/java/com/nhn/hippo/web/service/FlowChartService.java b/src/main/java/com/nhn/hippo/web/service/FlowChartService.java index d7edcecbb..18143ad8a 100755 --- a/src/main/java/com/nhn/hippo/web/service/FlowChartService.java +++ b/src/main/java/com/nhn/hippo/web/service/FlowChartService.java @@ -7,73 +7,17 @@ import com.nhn.hippo.web.calltree.server.ServerCallTree; import com.nhn.hippo.web.vo.Application; import com.nhn.hippo.web.vo.BusinessTransactions; import com.nhn.hippo.web.vo.TraceId; -import com.nhn.hippo.web.vo.scatter.Dot; /** * @author netspider */ public interface FlowChartService { - /** - * select agentIds from application name - * - * @param hosts - * @return - */ - public String[] selectAgentIdsFromApplicationName(String applicationName); - - /** - * select traceIds from TraceIndex table - * - * @param agentIds - * @param from - * @param to - * @return - */ - public Set selectTraceIdsFromTraceIndex(String[] agentIds, long from, long to); - - /** - * select traceIds from ApplicationTraceIndex table - * - * @param agentIds - * @param from - * @param to - * @return - */ public Set selectTraceIdsFromApplicationTraceIndex(String applicationName, long from, long to); - /** - * select call tree - * - * @param traceIds - * @return - */ - public ServerCallTree selectServerCallTree(Set traceIds); - - /** - * - * @param traceIds - * @param applicationName - * @param from - * @param to - * @return - */ - public ServerCallTree selectServerCallTree(Set traceIds, String applicationName, long from, long to); - - /** - * select all application names - * - * @return all of application names - */ public List selectAllApplicationNames(); - public String[] selectAgentIds(String[] hosts); - public ServerCallTree selectServerCallTree(TraceId traceId); - - public List selectScatterData(String applicationName, long from, long to); - - public List selectScatterData(String applicationName, long from, long to, int limit); - + public BusinessTransactions selectBusinessTransactions(Set traceIds, String applicationName, long from, long to); } diff --git a/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java b/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java index 83132bd16..37951372b 100755 --- a/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java +++ b/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java @@ -1,11 +1,8 @@ package com.nhn.hippo.web.service; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import org.slf4j.Logger; @@ -15,23 +12,14 @@ import org.springframework.stereotype.Service; import org.springframework.util.StopWatch; import com.nhn.hippo.web.calltree.server.AgentIdNodeSelector; -import com.nhn.hippo.web.calltree.server.ApplicationIdNodeSelector; import com.nhn.hippo.web.calltree.server.ServerCallTree; -import com.nhn.hippo.web.dao.AgentInfoDao; import com.nhn.hippo.web.dao.ApplicationIndexDao; import com.nhn.hippo.web.dao.ApplicationTraceIndexDao; -import com.nhn.hippo.web.dao.ClientStatisticsDao; -import com.nhn.hippo.web.dao.TerminalStatisticsDao; import com.nhn.hippo.web.dao.TraceDao; -import com.nhn.hippo.web.dao.TraceIndexDao; import com.nhn.hippo.web.vo.Application; import com.nhn.hippo.web.vo.BusinessTransactions; import com.nhn.hippo.web.vo.ClientStatistics; -import com.nhn.hippo.web.vo.TerminalStatistics; import com.nhn.hippo.web.vo.TraceId; -import com.nhn.hippo.web.vo.scatter.Dot; -import com.profiler.common.ServiceType; -import com.profiler.common.bo.AgentInfoBo; import com.profiler.common.bo.SpanBo; import com.profiler.common.bo.SpanEventBo; @@ -46,86 +34,17 @@ public class FlowChartServiceImpl implements FlowChartService { @Autowired private TraceDao traceDao; - @Autowired - private TraceIndexDao traceIndexDao; - @Autowired private ApplicationIndexDao applicationIndexDao; @Autowired private ApplicationTraceIndexDao applicationTraceIndexDao; - @Autowired - private TerminalStatisticsDao terminalStatisticsDao; - - @Autowired - private ClientStatisticsDao clientStatisticsDao; - - @Autowired - private AgentInfoDao agentInfoDao; - @Override public List selectAllApplicationNames() { return applicationIndexDao.selectAllApplicationNames(); } - @Override - public String[] selectAgentIdsFromApplicationName(String applicationName) { - return applicationIndexDao.selectAgentIds(applicationName); - } - - @Override - public Set selectTraceIdsFromTraceIndex(String[] agentIds, long from, long to) { - if (agentIds == null) { - throw new NullPointerException("agentIds"); - } - - if (agentIds.length == 1) { - // single scan - if (logger.isTraceEnabled()) { - logger.trace("scan {}, {}, {}", new Object[] { agentIds[0], from, to }); - } - List> bytes = this.traceIndexDao.scanTraceIndex(agentIds[0], from, to); - Set result = new HashSet(); - for (List list : bytes) { - for (TraceId traceId : list) { - result.add(traceId); - logger.trace("traceid:{}", traceId); - } - } - return result; - } else { - // multi scan 가능한 동일 open htable 에서 액세스함. - List>> multiScan = this.traceIndexDao.multiScanTraceIndex(agentIds, from, to); - Set result = new HashSet(); - for (List> list : multiScan) { - for (List scan : list) { - for (TraceId traceId : scan) { - result.add(traceId); - } - } - } - return result; - } - } - - @Deprecated - @Override - public ServerCallTree selectServerCallTree(Set traceIds) { - final ServerCallTree tree = new ServerCallTree(new ApplicationIdNodeSelector()); - - List> traces = this.traceDao.selectSpans(traceIds); - - for (List transaction : traces) { - // List processed = refine(transaction); - // markRecursiveCall(transaction); - for (SpanBo eachTransaction : transaction) { - tree.addSpan(eachTransaction); - } - } - return tree.build(); - } - /** * DetailView에서 사용함. 하나의 Span을 선택했을때 Draw되는 데이터를 생성하는 함수이다 makes call tree * of transaction detail view @@ -145,7 +64,7 @@ public class FlowChartServiceImpl implements FlowChartService { tree.addSpanEventList(spanEventBoList); tree.build(); - + watch.stop(); logger.info("Fetch single transaction serverCallTree elapsed. {}ms", watch.getLastTaskTimeMillis()); @@ -216,150 +135,6 @@ public class FlowChartServiceImpl implements FlowChartService { return endPointSet; } - private Set selectApplicationHosts(String applicationId) { - String[] agentIds = applicationIndexDao.selectAgentIds(applicationId); - - Set hostnames = new HashSet(); - - for (String agentId : agentIds) { - // TODO 조회 시간대에 따라서 agent info row timestamp를 변경하여 조회해야하는지는 모르겠음. - AgentInfoBo info = agentInfoDao.findAgentInfoBeforeStartTime(agentId, System.currentTimeMillis()); - hostnames.add(info.getHostname()); - } - - return hostnames; - } - - /** - * 메인화면에서 사용. 시간별로 TimeSlot을 조회하여 서버 맵을 그릴 때 사용한다. makes call tree of main - * view - */ - @Override - public ServerCallTree selectServerCallTree(Set traceIds, String applicationName, long from, long to) { - StopWatch watch = new StopWatch(); - watch.start(); - - final Map terminalQueryParams = new HashMap(); - final Map clientQueryParams = new HashMap(); - final Set hostnameQueryParams = new HashSet(); - final ServerCallTree tree = new ServerCallTree(new ApplicationIdNodeSelector()); - - // fetch non-terminal spans - List> traces = this.traceDao.selectSpans(traceIds); - - int totalNonTerminalSpansCount = 0; - - Set nonTerminalEndPoints = new HashSet(); - - // processing spans - for (List transaction : traces) { - totalNonTerminalSpansCount += transaction.size(); - - // List processed = refine(transaction); - // markRecursiveCall(transaction); - for (SpanBo eachTransaction : transaction) { - tree.addSpan(eachTransaction); - - // make hostname query params - hostnameQueryParams.add(eachTransaction.getApplicationId()); - - // make query param - terminalQueryParams.put(eachTransaction.getApplicationId(), eachTransaction.getServiceType()); - - // make client query param - if (eachTransaction.isRoot()) { - // TODO 여기에서 service type을 CLIENT로 지정해버려서 client유형별로 조회 불가능. 나중에 고쳐야함. - clientQueryParams.put(eachTransaction.getApplicationId(), ServiceType.CLIENT); - } - - nonTerminalEndPoints.add(eachTransaction.getEndPoint()); - } - } - - // fetch terminal info - for (Entry param : terminalQueryParams.entrySet()) { - ServiceType svcType = param.getValue(); - if (!svcType.isRpcClient() && !svcType.isUnknown() && !svcType.isTerminal()) { - long start = System.currentTimeMillis(); - List> terminals = terminalStatisticsDao.selectTerminal(param.getKey(), from, to); - logger.info(" Fetch terminals of {} : {}ms", param.getKey(), System.currentTimeMillis() - start); - - for (Map terminal : terminals) { - for (Entry entry : terminal.entrySet()) { - // TODO 임시방편 - TerminalStatistics terminalStatistics = entry.getValue(); - - // 이 요청의 destination이 수집된 trace정보에 없으면 unknown cloud로 처리한다. - if (!nonTerminalEndPoints.contains(terminalStatistics.getTo())) { - - if (ServiceType.findServiceType(terminalStatistics.getToServiceType()).isRpcClient()) { - terminalStatistics.setToServiceType(ServiceType.UNKNOWN_CLOUD.getCode()); - } - - tree.addTerminalStatistics(terminalStatistics); - } - } - } - } - } - - logger.debug("client query params=" + clientQueryParams); - - // fetch client info - for (Entry param : clientQueryParams.entrySet()) { - List> clients = clientStatisticsDao.selectClient(param.getKey(), param.getValue().getCode(), from, to); - - for (Map client : clients) { - for (Entry clientEntry : client.entrySet()) { - logger.debug("fetched client=" + clientEntry); - tree.addClientStatistics(clientEntry.getValue()); - } - } - } - - logger.debug("hostname query params=" + hostnameQueryParams); - - // fetch hostnames - for (String applicationId : hostnameQueryParams) { - tree.addApplicationHosts(applicationId, selectApplicationHosts(applicationId)); - } - - tree.build(); - - watch.stop(); - logger.info("Fetch serverCallTree elapsed. {}ms", watch.getLastTaskTimeMillis()); - - return tree; - } - - @Deprecated - private SpanBo findChildSpan(final List list, final SpanBo parent) { - for (int i = 0; i < list.size(); i++) { - SpanBo child = list.get(i); - - if (child.getParentSpanId() == parent.getSpanId()) { - return child; - } - } - return null; - } - - /** - * server map이 recursive call을 표현할 수 있게 되어 필요 없음. - * - * @param list - */ - @Deprecated - private void markRecursiveCall(final List list) { - /* - * for (int i = 0; i < list.size(); i++) { SpanBo a = list.get(i); for - * (int j = 0; j < list.size(); j++) { if (i == j) continue; SpanBo b = - * list.get(j); if (a.getServiceName().equals(b.getServiceName()) && - * a.getSpanId() == b.getParentSpanId()) { - * a.increaseRecursiveCallCount(); } } } - */ - } - @Override public Set selectTraceIdsFromApplicationTraceIndex(String applicationName, long from, long to) { if (applicationName == null) { @@ -381,55 +156,13 @@ public class FlowChartServiceImpl implements FlowChartService { return result; } - @Deprecated - @Override - public String[] selectAgentIds(String[] hosts) { - // List column = new ArrayList(); - // column.add(new HbaseColumn("Agents", "AgentID")); - // - // HBaseQuery query = new HBaseQuery(HBaseTables.APPLICATION_INDEX, - // null, null, column); - // Iterator> iterator = client.getHBaseData(query); - // - // if (logger.isDebugEnabled()) { - // while (iterator.hasNext()) { - // logger.debug("selectedAgentId={}", iterator.next()); - // } - // logger.debug("!!!==============WARNING==============!!!"); - // logger.debug("!!! selectAgentIds IS NOT IMPLEMENTED !!!"); - // logger.debug("!!!===================================!!!"); - // } - - return hosts; - } - - @Override - public List selectScatterData(String applicationName, long from, long to) { - List> scanTrace = applicationTraceIndexDao.scanTraceScatter(applicationName, from, to); - - List list = new ArrayList(); - - for (List l : scanTrace) { - for (Dot dot : l) { - list.add(dot); - } - } - - return list; - } - - @Override - public List selectScatterData(String applicationName, long from, long to, int limit) { - return applicationTraceIndexDao.scanTraceScatter2(applicationName, from, to, limit); - } - @Override public BusinessTransactions selectBusinessTransactions(Set traceIds, String applicationName, long from, long to) { List> traceList = this.traceDao.selectSpans(traceIds); BusinessTransactions businessTransactions = new BusinessTransactions(); for (List trace : traceList) { - for (SpanBo spanBo : trace ) { + for (SpanBo spanBo : trace) { // 해당 application으로 인입된 요청만 보여준다. if (applicationName.equals(spanBo.getApplicationId())) { businessTransactions.add(spanBo); diff --git a/src/main/java/com/nhn/hippo/web/service/RecordSetService.java b/src/main/java/com/nhn/hippo/web/service/RecordSetService.java index 6875e8c15..b4c013b55 100644 --- a/src/main/java/com/nhn/hippo/web/service/RecordSetService.java +++ b/src/main/java/com/nhn/hippo/web/service/RecordSetService.java @@ -1,10 +1,10 @@ package com.nhn.hippo.web.service; +import java.util.List; + import com.nhn.hippo.web.calltree.span.SpanAlign; import com.nhn.hippo.web.vo.callstacks.RecordSet; -import java.util.List; - /** * */ diff --git a/src/main/java/com/nhn/hippo/web/service/RecordSetServiceImpl.java b/src/main/java/com/nhn/hippo/web/service/RecordSetServiceImpl.java index da01a5b05..92d20c11d 100644 --- a/src/main/java/com/nhn/hippo/web/service/RecordSetServiceImpl.java +++ b/src/main/java/com/nhn/hippo/web/service/RecordSetServiceImpl.java @@ -1,6 +1,12 @@ package com.nhn.hippo.web.service; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.ObjectUtils; +import org.springframework.stereotype.Service; + import com.nhn.hippo.web.calltree.span.SpanAlign; import com.nhn.hippo.web.vo.callstacks.Record; import com.nhn.hippo.web.vo.callstacks.RecordSet; @@ -11,11 +17,6 @@ import com.profiler.common.bo.SpanEventBo; import com.profiler.common.util.AnnotationUtils; import com.profiler.common.util.ApiDescription; import com.profiler.common.util.ApiDescriptionParser; -import org.apache.commons.lang.ObjectUtils; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; /** * diff --git a/src/main/java/com/nhn/hippo/web/service/ScatterChartService.java b/src/main/java/com/nhn/hippo/web/service/ScatterChartService.java new file mode 100644 index 000000000..b8e998fbd --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/service/ScatterChartService.java @@ -0,0 +1,13 @@ +package com.nhn.hippo.web.service; + +import java.util.List; + +import com.nhn.hippo.web.vo.TransactionMetadataQuery; +import com.nhn.hippo.web.vo.scatter.Dot; +import com.profiler.common.bo.SpanBo; + +public interface ScatterChartService { + public List selectScatterData(String applicationName, long from, long to, int limit); + + public List selectTransactionMetadata(TransactionMetadataQuery query); +} diff --git a/src/main/java/com/nhn/hippo/web/service/ScatterChartServiceImpl.java b/src/main/java/com/nhn/hippo/web/service/ScatterChartServiceImpl.java new file mode 100644 index 000000000..47f1808a4 --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/service/ScatterChartServiceImpl.java @@ -0,0 +1,71 @@ +package com.nhn.hippo.web.service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.nhn.hippo.web.dao.ApplicationTraceIndexDao; +import com.nhn.hippo.web.dao.TraceDao; +import com.nhn.hippo.web.vo.TransactionMetadataQuery; +import com.nhn.hippo.web.vo.scatter.Dot; +import com.profiler.common.bo.SpanBo; + +/** + * @author netspider + */ +@Service +public class ScatterChartServiceImpl implements ScatterChartService { + + @Autowired + private ApplicationTraceIndexDao applicationTraceIndexDao; + + @Autowired + private TraceDao traceDao; + + @Override + public List selectScatterData(String applicationName, long from, long to, int limit) { + return applicationTraceIndexDao.scanTraceScatter2(applicationName, from, to, limit); + } + + /** + * scatter chart에서 선택한 점에 대한 정보를 조회 하는 메소드. + */ + @Override + public List selectTransactionMetadata(TransactionMetadataQuery query) { + List> selectedSpans = traceDao.selectSpans(query.getTraceIds()); + + List result = new ArrayList(query.size()); + + // 조회된 녀석들 중에서 UUID, starttime, responseTime이 같은것들만 골라냄. + for (List spans : selectedSpans) { + for (SpanBo span : spans) { + // check UUID and time + if (query.isExists(span.getMostTraceId(), span.getLeastTraceId(), span.getCollectorAcceptTime(), span.getElapsed())) { + result.add(span); + } + } + } + + // TODO 일단 임시로... + Collections.sort(result, new Comparator() { + @Override + public int compare(SpanBo o1, SpanBo o2) { + if (o1.getException() != 0 && o2.getException() != 0) { + return o2.getElapsed() - o1.getElapsed(); + } else if (o1.getException() != 0) { + return -1; + } else if (o2.getException() != 0) { + return 1; + } else { + return o2.getElapsed() - o1.getElapsed(); + } + } + }); + + return result; + } +} diff --git a/src/main/java/com/nhn/hippo/web/service/SpanService.java b/src/main/java/com/nhn/hippo/web/service/SpanService.java index 59493e2df..d9e9c7920 100644 --- a/src/main/java/com/nhn/hippo/web/service/SpanService.java +++ b/src/main/java/com/nhn/hippo/web/service/SpanService.java @@ -3,15 +3,11 @@ package com.nhn.hippo.web.service; import java.util.List; import com.nhn.hippo.web.calltree.span.SpanAlign; -import com.nhn.hippo.web.vo.RequestMetadataQuery; import com.nhn.hippo.web.vo.TraceId; -import com.profiler.common.bo.SpanBo; /** * */ public interface SpanService { List selectSpan(TraceId traceId); - - List selectRequestMetadata(RequestMetadataQuery query); } diff --git a/src/main/java/com/nhn/hippo/web/service/SpanServiceImpl.java b/src/main/java/com/nhn/hippo/web/service/SpanServiceImpl.java index d26c221b1..528379d15 100644 --- a/src/main/java/com/nhn/hippo/web/service/SpanServiceImpl.java +++ b/src/main/java/com/nhn/hippo/web/service/SpanServiceImpl.java @@ -1,12 +1,8 @@ package com.nhn.hippo.web.service; -import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; -import com.nhn.hippo.web.vo.TraceId; -import com.profiler.common.AnnotationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +14,8 @@ import com.nhn.hippo.web.dao.AgentInfoDao; import com.nhn.hippo.web.dao.ApiMetaDataDao; import com.nhn.hippo.web.dao.SqlMetaDataDao; import com.nhn.hippo.web.dao.TraceDao; -import com.nhn.hippo.web.vo.RequestMetadataQuery; +import com.nhn.hippo.web.vo.TraceId; +import com.profiler.common.AnnotationKey; import com.profiler.common.bo.AgentInfoBo; import com.profiler.common.bo.AnnotationBo; import com.profiler.common.bo.ApiMetaDataBo; @@ -36,379 +33,335 @@ import com.profiler.common.util.SqlParser; @Service public class SpanServiceImpl implements SpanService { - private Logger logger = LoggerFactory.getLogger(this.getClass()); + private Logger logger = LoggerFactory.getLogger(this.getClass()); - @Autowired - private TraceDao traceDao; + @Autowired + private TraceDao traceDao; - @Autowired - private SqlMetaDataDao sqlMetaDataDao; + @Autowired + private SqlMetaDataDao sqlMetaDataDao; - @Autowired - private ApiMetaDataDao apiMetaDataDao; + @Autowired + private ApiMetaDataDao apiMetaDataDao; - @Autowired - private AgentInfoDao agentInfoDao; + @Autowired + private AgentInfoDao agentInfoDao; - private SqlParser sqlParser = new SqlParser(); - private OutputParameterParser outputParameterParser = new OutputParameterParser(); + private SqlParser sqlParser = new SqlParser(); + private OutputParameterParser outputParameterParser = new OutputParameterParser(); - @Override - public List selectSpan(TraceId traceId) { + @Override + public List selectSpan(TraceId traceId) { - List spans = traceDao.selectSpanAndAnnotation(traceId); - if (spans == null || spans.isEmpty()) { - return Collections.emptyList(); - } + List spans = traceDao.selectSpanAndAnnotation(traceId); + if (spans == null || spans.isEmpty()) { + return Collections.emptyList(); + } - List order = order(spans); - transitionApiId(order); - transitionDynamicApiId(order); - transitionSqlId(order); - // TODO root span not found시 row data라도 보여줘야 됨. + List order = order(spans); + transitionApiId(order); + transitionDynamicApiId(order); + transitionSqlId(order); + // TODO root span not found시 row data라도 보여줘야 됨. - return order; - } + return order; + } + private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { + for (SpanAlign spanAlign : spans) { + List annotationBoList; + if (spanAlign.isSpan()) { + annotationBoList = spanAlign.getSpanBo().getAnnotationBoList(); + annotationReplacementCallback.replacement(spanAlign, annotationBoList); + } else { + annotationBoList = spanAlign.getSpanEventBo().getAnnotationBoList(); + annotationReplacementCallback.replacement(spanAlign, annotationBoList); + } + } + } - private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { - for (SpanAlign spanAlign : spans) { - List annotationBoList; - if (spanAlign.isSpan()) { - annotationBoList = spanAlign.getSpanBo().getAnnotationBoList(); - annotationReplacementCallback.replacement(spanAlign, annotationBoList); - } else { - annotationBoList = spanAlign.getSpanEventBo().getAnnotationBoList(); - annotationReplacementCallback.replacement(spanAlign, annotationBoList); - } - } - } - - private void transitionSqlId(final List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.SQL_ID.getCode()); - if (sqlIdAnnotation == null) { - return; - } - - AgentInfoBo agentInfoBo = null; - try { - agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); - logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); - } catch (AgentIdNotFoundException ex) { - AnnotationBo agentInfoNotFound = new AnnotationBo(); - agentInfoNotFound.setKey(AnnotationKey.SQL.getCode()); - agentInfoNotFound.setValue("SQL-ID not found. Cause:agentInfo not found. agentId:" + ex.getAgentId() + " startTime:" + ex.getStartTime()); - annotationBoList.add(agentInfoNotFound); - return; - } - - // TODO 일단 시간까지 조회는 하지 말고 하자. - // 미리 sqlMetaDataList를 indentifier로 필터치는 로직이 더 좋을것으로 생각됨. - int hashCode = (Integer) sqlIdAnnotation.getValue(); - List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), hashCode, agentInfoBo.getTimestamp()); - int size = sqlMetaDataList.size(); - if (size == 0) { - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.SQL.getCode()); - api.setValue("SQL-ID not found hashCode:" + hashCode); - annotationBoList.add(api); - } else if (size == 1) { - AnnotationBo sqlParamAnnotationBo = findAnnotation(annotationBoList, AnnotationKey.SQL_PARAM.getCode()); - final SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(0); - if (sqlParamAnnotationBo == null) { - AnnotationBo sqlMeta = new AnnotationBo(); - sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); - sqlMeta.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sqlMeta); - - AnnotationBo checkFail = checkIdentifier (spanAlign, sqlMetaDataBo); - if (checkFail != null) { - // 실패 - annotationBoList.add(checkFail); - return; - } - - AnnotationBo sql = new AnnotationBo(); - sql.setKey(AnnotationKey.SQL.getCode()); - sql.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sql); - } else { - logger.debug("sqlMetaDataBo:{}", sqlMetaDataBo); - String outputParams = (String) sqlParamAnnotationBo.getValue(); - List parsedOutputParams = outputParameterParser.parseOutputParameter(outputParams); - logger.debug("outputPrams:{}, parsedOutputPrams:{}", outputParams, parsedOutputParams); - String originalSql = sqlParser.combineOutputParams(sqlMetaDataBo.getSql(), parsedOutputParams); - logger.debug("outputPrams{}, originalSql:{}", outputParams, originalSql); - - - AnnotationBo sqlMeta = new AnnotationBo(); - sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); - sqlMeta.setValue(sqlMetaDataBo.getSql()); - annotationBoList.add(sqlMeta); - - AnnotationBo checkFail = checkIdentifier (spanAlign, sqlMetaDataBo); - if (checkFail != null) { - // 실패 - annotationBoList.add(checkFail); - return; - } - - - AnnotationBo sql = new AnnotationBo(); - sql.setKey(AnnotationKey.SQL.getCode()); - sql.setValue(originalSql); - annotationBoList.add(sql); - - - } - } else { - // TODO 보완해야됨. - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.SQL.getCode()); - api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList)); - annotationBoList.add(api); - } - - } - - private AnnotationBo checkIdentifier(SpanAlign spanAlign, SqlMetaDataBo sqlMetaDataBo) { - short agentIdentifier = getAgentIdentifier(spanAlign); - short sqlIdentifier = sqlMetaDataBo.getIdentifier(); - if (agentIdentifier == sqlIdentifier) { - return null; - } - AnnotationBo identifierCheckFail = new AnnotationBo(); - identifierCheckFail.setKey(AnnotationKey.SQL.getCode()); - identifierCheckFail.setValue("invalid SqlMetaInfo:" + sqlMetaDataBo); - return identifierCheckFail; - } - }); - } - - private AnnotationBo findAnnotation(List annotationBoList, int key) { - for (AnnotationBo annotationBo : annotationBoList) { - if (key == annotationBo.getKey()) { - return annotationBo; - } - } - return null; - } - - - private String collisionSqlHashCodeMessage(int hashCode, List sqlMetaDataList) { - // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. - StringBuilder sb = new StringBuilder(64); - sb.append("Collision Sql hashCode:"); - sb.append(hashCode); - sb.append('\n'); - for (int i = 0; i < sqlMetaDataList.size(); i++) { - if (i != 0) { - sb.append("or\n"); - } - SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i); - sb.append(sqlMetaDataBo.getSql()); - } - return sb.toString(); - } - - private String getAgentId(SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - return spanAlign.getSpanBo().getAgentId(); - } else { - return spanAlign.getSpanEventBo().getAgentId(); - } - } - - private short getAgentIdentifier(SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - return spanAlign.getSpanBo().getAgentIdentifier(); - } else { - return spanAlign.getSpanEventBo().getAgentIdentifier(); - } - } - - private void transitionDynamicApiId(List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.API_DID.getCode()); - if (apiIdAnnotation == null) { - return; - } - - AgentInfoBo agentInfoBo = null; - try { - agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); - logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); - } catch (AgentIdNotFoundException ex) { - AnnotationBo agentInfoNotFound = new AnnotationBo(); - agentInfoNotFound.setKey(AnnotationKey.ERROR_API_METADATA_AGENT_INFO_NOT_FOUND.getCode()); - agentInfoNotFound.setValue("API-DynamicID not found. Cause:agentInfo not found. agentId:" + ex.getAgentId() + " startTime:" + ex.getStartTime()); - annotationBoList.add(agentInfoNotFound); - return; - } - - int apiId = (Integer) apiIdAnnotation.getValue(); - List apiMetaDataList = apiMetaDataDao.getApiMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), apiId, agentInfoBo.getTimestamp()); - int size = apiMetaDataList.size(); - if (size == 0) { - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); - api.setValue("API-DynamicID not found. api:" + apiId); - annotationBoList.add(api); - } else if (size == 1) { - ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(0); - AnnotationBo apiMetaData = new AnnotationBo(); - apiMetaData.setKey(AnnotationKey.API_METADATA.getCode()); - apiMetaData.setValue(apiMetaDataBo); - annotationBoList.add(apiMetaData); - - - AnnotationBo checkFail = checkIdentifier (spanAlign, apiMetaDataBo); - if (checkFail != null) { - // 실패 - annotationBoList.add(checkFail); - return; - } - - AnnotationBo apiAnnotation = new AnnotationBo(); - apiAnnotation.setKey(AnnotationKey.API.getCode()); - String apiInfo = getApiInfo(apiMetaDataBo); - apiAnnotation.setValue(apiInfo); - annotationBoList.add(apiAnnotation); - } else { - AnnotationBo apiAnnotation = new AnnotationBo(); - apiAnnotation.setKey(AnnotationKey.ERROR_API_METADATA_DID_COLLSION.getCode()); - String collisonMessage = collisionApiDidMessage(apiId, apiMetaDataList); - apiAnnotation.setValue(collisonMessage); - annotationBoList.add(apiAnnotation); - } - - - - } - - private AnnotationBo checkIdentifier(SpanAlign spanAlign, ApiMetaDataBo apiMetaDataBo) { - short agentIdentifier = getAgentIdentifier(spanAlign); - short sqlIdentifier = apiMetaDataBo.getIdentifier(); - if (agentIdentifier == sqlIdentifier) { - return null; - } - AnnotationBo identifierCheckFail = new AnnotationBo(); - identifierCheckFail.setKey(AnnotationKey.ERROR_API_METADATA_IDENTIFIER_CHECK_ERROR.getCode()); - identifierCheckFail.setValue("invalid ApiMetaInfo:" + apiMetaDataBo); - return identifierCheckFail; - } - - }); - } - - private AgentInfoBo findAgentInfoBoBeforeStartTime(SpanAlign spanAlign) { - String agentId = getAgentId(spanAlign); - long startTime = spanAlign.getSpanBo().getStartTime(); - AgentInfoBo agentInfoBeforeStartTime = agentInfoDao.findAgentInfoBeforeStartTime(agentId, startTime); - if (agentInfoBeforeStartTime == null) { - throw new AgentIdNotFoundException(agentId, startTime); - } - return agentInfoBeforeStartTime; - } - - private String collisionApiDidMessage(int apidId, List apiMetaDataList) { - // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. - StringBuilder sb = new StringBuilder(64); - sb.append("Collision Api DynamicId:"); - sb.append(apidId); - sb.append('\n'); - for (int i = 0; i < apiMetaDataList.size(); i++) { - if (i != 0) { - sb.append("or\n"); - } - ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(i); - sb.append(getApiInfo(apiMetaDataBo)); - } - return sb.toString(); - } - - private String getApiInfo(ApiMetaDataBo apiMetaDataBo) { - if (apiMetaDataBo.getLineNumber() != -1) { - return apiMetaDataBo.getApiInfo() + ":" + apiMetaDataBo.getLineNumber(); - } else { - return apiMetaDataBo.getApiInfo(); - } - } - - private void transitionApiId(List spans) { - this.transitionAnnotation(spans, new AnnotationReplacementCallback() { - @Override - public void replacement(SpanAlign spanAlign, List annotationBoList) { - AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.API_ID.getCode()); - if (apiIdAnnotation == null) { - return; - } - - MethodMapping methodMapping = ApiMappingTable.findMethodMapping((Integer) apiIdAnnotation.getValue()); - if (methodMapping == null) { - return; - } - String className = methodMapping.getClassMapping().getClassName(); - String methodName = methodMapping.getMethodName(); - String[] parameterType = methodMapping.getParameterType(); - String[] parameterName = methodMapping.getParameterName(); - String args = ApiUtils.mergeParameterVariableNameDescription(parameterType, parameterName); - AnnotationBo api = new AnnotationBo(); - api.setKey(AnnotationKey.API.getCode()); - api.setValue(className + "." + methodName + args); - annotationBoList.add(api); - } - }); - } - - - public static interface AnnotationReplacementCallback { - void replacement(SpanAlign spanAlign, List annotationBoList); - } - - private List order(List spans) { - SpanAligner2 spanAligner = new SpanAligner2(spans); - return spanAligner.sort(); - - } - - @Override - public List selectRequestMetadata(RequestMetadataQuery query) { - List> selectedSpans = traceDao.selectSpans(query.getTraceIds()); - - List result = new ArrayList(query.size()); - - // 조회된 녀석들 중에서 UUID, starttime, responseTime이 같은것들만 골라냄. - for (List spans : selectedSpans) { - for (SpanBo span : spans) { - // check UUID and time - if (query.isExists(span.getMostTraceId(), span.getLeastTraceId(), span.getCollectorAcceptTime(), span.getElapsed())) { - result.add(span); - } - } - } - - // TODO 일단 임시로... - Collections.sort(result, new Comparator() { + private void transitionSqlId(final List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { @Override - public int compare(SpanBo o1, SpanBo o2) { - if (o1.getException() != 0 && o2.getException() != 0) { - return o2.getElapsed() - o1.getElapsed(); - } else if (o1.getException() != 0) { - return -1; - } else if (o2.getException() != 0) { - return 1; - } else { - return o2.getElapsed() - o1.getElapsed(); + public void replacement(SpanAlign spanAlign, List annotationBoList) { + AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.SQL_ID.getCode()); + if (sqlIdAnnotation == null) { + return; } + + AgentInfoBo agentInfoBo = null; + try { + agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); + logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); + } catch (AgentIdNotFoundException ex) { + AnnotationBo agentInfoNotFound = new AnnotationBo(); + agentInfoNotFound.setKey(AnnotationKey.SQL.getCode()); + agentInfoNotFound.setValue("SQL-ID not found. Cause:agentInfo not found. agentId:" + ex.getAgentId() + " startTime:" + ex.getStartTime()); + annotationBoList.add(agentInfoNotFound); + return; + } + + // TODO 일단 시간까지 조회는 하지 말고 하자. + // 미리 sqlMetaDataList를 indentifier로 필터치는 로직이 더 좋을것으로 생각됨. + int hashCode = (Integer) sqlIdAnnotation.getValue(); + List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), hashCode, agentInfoBo.getTimestamp()); + int size = sqlMetaDataList.size(); + if (size == 0) { + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.SQL.getCode()); + api.setValue("SQL-ID not found hashCode:" + hashCode); + annotationBoList.add(api); + } else if (size == 1) { + AnnotationBo sqlParamAnnotationBo = findAnnotation(annotationBoList, AnnotationKey.SQL_PARAM.getCode()); + final SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(0); + if (sqlParamAnnotationBo == null) { + AnnotationBo sqlMeta = new AnnotationBo(); + sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); + sqlMeta.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sqlMeta); + + AnnotationBo checkFail = checkIdentifier(spanAlign, sqlMetaDataBo); + if (checkFail != null) { + // 실패 + annotationBoList.add(checkFail); + return; + } + + AnnotationBo sql = new AnnotationBo(); + sql.setKey(AnnotationKey.SQL.getCode()); + sql.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sql); + } else { + logger.debug("sqlMetaDataBo:{}", sqlMetaDataBo); + String outputParams = (String) sqlParamAnnotationBo.getValue(); + List parsedOutputParams = outputParameterParser.parseOutputParameter(outputParams); + logger.debug("outputPrams:{}, parsedOutputPrams:{}", outputParams, parsedOutputParams); + String originalSql = sqlParser.combineOutputParams(sqlMetaDataBo.getSql(), parsedOutputParams); + logger.debug("outputPrams{}, originalSql:{}", outputParams, originalSql); + + AnnotationBo sqlMeta = new AnnotationBo(); + sqlMeta.setKey(AnnotationKey.SQL_METADATA.getCode()); + sqlMeta.setValue(sqlMetaDataBo.getSql()); + annotationBoList.add(sqlMeta); + + AnnotationBo checkFail = checkIdentifier(spanAlign, sqlMetaDataBo); + if (checkFail != null) { + // 실패 + annotationBoList.add(checkFail); + return; + } + + AnnotationBo sql = new AnnotationBo(); + sql.setKey(AnnotationKey.SQL.getCode()); + sql.setValue(originalSql); + annotationBoList.add(sql); + + } + } else { + // TODO 보완해야됨. + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.SQL.getCode()); + api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList)); + annotationBoList.add(api); + } + + } + + private AnnotationBo checkIdentifier(SpanAlign spanAlign, SqlMetaDataBo sqlMetaDataBo) { + short agentIdentifier = getAgentIdentifier(spanAlign); + short sqlIdentifier = sqlMetaDataBo.getIdentifier(); + if (agentIdentifier == sqlIdentifier) { + return null; + } + AnnotationBo identifierCheckFail = new AnnotationBo(); + identifierCheckFail.setKey(AnnotationKey.SQL.getCode()); + identifierCheckFail.setValue("invalid SqlMetaInfo:" + sqlMetaDataBo); + return identifierCheckFail; } }); - - return result; - } + } + + private AnnotationBo findAnnotation(List annotationBoList, int key) { + for (AnnotationBo annotationBo : annotationBoList) { + if (key == annotationBo.getKey()) { + return annotationBo; + } + } + return null; + } + + private String collisionSqlHashCodeMessage(int hashCode, List sqlMetaDataList) { + // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. + StringBuilder sb = new StringBuilder(64); + sb.append("Collision Sql hashCode:"); + sb.append(hashCode); + sb.append('\n'); + for (int i = 0; i < sqlMetaDataList.size(); i++) { + if (i != 0) { + sb.append("or\n"); + } + SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i); + sb.append(sqlMetaDataBo.getSql()); + } + return sb.toString(); + } + + private String getAgentId(SpanAlign spanAlign) { + if (spanAlign.isSpan()) { + return spanAlign.getSpanBo().getAgentId(); + } else { + return spanAlign.getSpanEventBo().getAgentId(); + } + } + + private short getAgentIdentifier(SpanAlign spanAlign) { + if (spanAlign.isSpan()) { + return spanAlign.getSpanBo().getAgentIdentifier(); + } else { + return spanAlign.getSpanEventBo().getAgentIdentifier(); + } + } + + private void transitionDynamicApiId(List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.API_DID.getCode()); + if (apiIdAnnotation == null) { + return; + } + + AgentInfoBo agentInfoBo = null; + try { + agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); + logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); + } catch (AgentIdNotFoundException ex) { + AnnotationBo agentInfoNotFound = new AnnotationBo(); + agentInfoNotFound.setKey(AnnotationKey.ERROR_API_METADATA_AGENT_INFO_NOT_FOUND.getCode()); + agentInfoNotFound.setValue("API-DynamicID not found. Cause:agentInfo not found. agentId:" + ex.getAgentId() + " startTime:" + ex.getStartTime()); + annotationBoList.add(agentInfoNotFound); + return; + } + + int apiId = (Integer) apiIdAnnotation.getValue(); + List apiMetaDataList = apiMetaDataDao.getApiMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), apiId, agentInfoBo.getTimestamp()); + int size = apiMetaDataList.size(); + if (size == 0) { + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); + api.setValue("API-DynamicID not found. api:" + apiId); + annotationBoList.add(api); + } else if (size == 1) { + ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(0); + AnnotationBo apiMetaData = new AnnotationBo(); + apiMetaData.setKey(AnnotationKey.API_METADATA.getCode()); + apiMetaData.setValue(apiMetaDataBo); + annotationBoList.add(apiMetaData); + + AnnotationBo checkFail = checkIdentifier(spanAlign, apiMetaDataBo); + if (checkFail != null) { + // 실패 + annotationBoList.add(checkFail); + return; + } + + AnnotationBo apiAnnotation = new AnnotationBo(); + apiAnnotation.setKey(AnnotationKey.API.getCode()); + String apiInfo = getApiInfo(apiMetaDataBo); + apiAnnotation.setValue(apiInfo); + annotationBoList.add(apiAnnotation); + } else { + AnnotationBo apiAnnotation = new AnnotationBo(); + apiAnnotation.setKey(AnnotationKey.ERROR_API_METADATA_DID_COLLSION.getCode()); + String collisonMessage = collisionApiDidMessage(apiId, apiMetaDataList); + apiAnnotation.setValue(collisonMessage); + annotationBoList.add(apiAnnotation); + } + + } + + private AnnotationBo checkIdentifier(SpanAlign spanAlign, ApiMetaDataBo apiMetaDataBo) { + short agentIdentifier = getAgentIdentifier(spanAlign); + short sqlIdentifier = apiMetaDataBo.getIdentifier(); + if (agentIdentifier == sqlIdentifier) { + return null; + } + AnnotationBo identifierCheckFail = new AnnotationBo(); + identifierCheckFail.setKey(AnnotationKey.ERROR_API_METADATA_IDENTIFIER_CHECK_ERROR.getCode()); + identifierCheckFail.setValue("invalid ApiMetaInfo:" + apiMetaDataBo); + return identifierCheckFail; + } + + }); + } + + private AgentInfoBo findAgentInfoBoBeforeStartTime(SpanAlign spanAlign) { + String agentId = getAgentId(spanAlign); + long startTime = spanAlign.getSpanBo().getStartTime(); + AgentInfoBo agentInfoBeforeStartTime = agentInfoDao.findAgentInfoBeforeStartTime(agentId, startTime); + if (agentInfoBeforeStartTime == null) { + throw new AgentIdNotFoundException(agentId, startTime); + } + return agentInfoBeforeStartTime; + } + + private String collisionApiDidMessage(int apidId, List apiMetaDataList) { + // TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음. + StringBuilder sb = new StringBuilder(64); + sb.append("Collision Api DynamicId:"); + sb.append(apidId); + sb.append('\n'); + for (int i = 0; i < apiMetaDataList.size(); i++) { + if (i != 0) { + sb.append("or\n"); + } + ApiMetaDataBo apiMetaDataBo = apiMetaDataList.get(i); + sb.append(getApiInfo(apiMetaDataBo)); + } + return sb.toString(); + } + + private String getApiInfo(ApiMetaDataBo apiMetaDataBo) { + if (apiMetaDataBo.getLineNumber() != -1) { + return apiMetaDataBo.getApiInfo() + ":" + apiMetaDataBo.getLineNumber(); + } else { + return apiMetaDataBo.getApiInfo(); + } + } + + private void transitionApiId(List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationKey.API_ID.getCode()); + if (apiIdAnnotation == null) { + return; + } + + MethodMapping methodMapping = ApiMappingTable.findMethodMapping((Integer) apiIdAnnotation.getValue()); + if (methodMapping == null) { + return; + } + String className = methodMapping.getClassMapping().getClassName(); + String methodName = methodMapping.getMethodName(); + String[] parameterType = methodMapping.getParameterType(); + String[] parameterName = methodMapping.getParameterName(); + String args = ApiUtils.mergeParameterVariableNameDescription(parameterType, parameterName); + AnnotationBo api = new AnnotationBo(); + api.setKey(AnnotationKey.API.getCode()); + api.setValue(className + "." + methodName + args); + annotationBoList.add(api); + } + }); + } + + public static interface AnnotationReplacementCallback { + void replacement(SpanAlign spanAlign, List annotationBoList); + } + + private List order(List spans) { + SpanAligner2 spanAligner = new SpanAligner2(spans); + return spanAligner.sort(); + + } } diff --git a/src/main/java/com/nhn/hippo/web/vo/RequestMetadata.java b/src/main/java/com/nhn/hippo/web/vo/RequestMetadata.java deleted file mode 100644 index 6165515a5..000000000 --- a/src/main/java/com/nhn/hippo/web/vo/RequestMetadata.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.nhn.hippo.web.vo; - -import com.profiler.common.util.TraceIdUtils; - -/** - * UI로 이 객체 대신 SpanBO를 던진다. - * - * @author netspider - * - */ -@Deprecated -public class RequestMetadata { - - private final String traceId; - private final long startTime; - private final int elapsed; - private final String application; - - public RequestMetadata(long mostTraceId, long leastTraceId, long startTime, int elapsed, String application) { - this.traceId = TraceIdUtils.formatString(mostTraceId, leastTraceId); - this.startTime = startTime; - this.elapsed = elapsed; - this.application = application; - } - - public String getTraceId() { - return traceId; - } - - public long getStartTime() { - return startTime; - } - - public int getElapsed() { - return elapsed; - } - - public String getApplication() { - return application; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(traceId); - sb.append(startTime); - sb.append(elapsed); - sb.append(application); - return sb.toString(); - } -} diff --git a/src/main/java/com/nhn/hippo/web/vo/RequestMetadataQuery.java b/src/main/java/com/nhn/hippo/web/vo/TransactionMetadataQuery.java similarity index 94% rename from src/main/java/com/nhn/hippo/web/vo/RequestMetadataQuery.java rename to src/main/java/com/nhn/hippo/web/vo/TransactionMetadataQuery.java index 970136f88..2674b2209 100644 --- a/src/main/java/com/nhn/hippo/web/vo/RequestMetadataQuery.java +++ b/src/main/java/com/nhn/hippo/web/vo/TransactionMetadataQuery.java @@ -13,12 +13,12 @@ import java.util.Set; * @author netspider * */ -public class RequestMetadataQuery { +public class TransactionMetadataQuery { private final Map queryConditions; - public RequestMetadataQuery() { - queryConditions = new HashMap(); + public TransactionMetadataQuery() { + queryConditions = new HashMap(); } public void addQueryCondition(String traceId, long time, int responseTime) { diff --git a/src/main/webapp/WEB-INF/views/flowserver.jsp b/src/main/webapp/WEB-INF/views/flowserver.jsp deleted file mode 100644 index 5aa0d003d..000000000 --- a/src/main/webapp/WEB-INF/views/flowserver.jsp +++ /dev/null @@ -1,32 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ -"graphdata" : { - "nodes" : [ - - { - "name" : "${node}", - "agentIds" : [ - - "${agentId}" - , - - ], - "serviceType" : "${node.serviceType}", - "terminal" : "${node.serviceType.terminal}" - } , - - ], - "links" : [ - - { - "source" : ${link.from.sequence}, - "target" : ${link.to.sequence}, - "value" : ${link.requestCount}, - "histogram" : ${link.histogram} - } , - - ] - } -} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/scatter_view.jsp b/src/main/webapp/WEB-INF/views/scatter_view.jsp deleted file mode 100644 index d127c437a..000000000 --- a/src/main/webapp/WEB-INF/views/scatter_view.jsp +++ /dev/null @@ -1,331 +0,0 @@ - - - - HIPPO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/servermap.jsp b/src/main/webapp/WEB-INF/views/servermap.jsp deleted file mode 100644 index ca99976e3..000000000 --- a/src/main/webapp/WEB-INF/views/servermap.jsp +++ /dev/null @@ -1,34 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -{ -"graphdata" : { - "nodes" : [ - - { - "name" : "${node}", - "hosts" : [ - - "${host}" - , - - ], - "serviceType" : "${node.serviceType.desc}", - "terminal" : "${node.serviceType.terminal}" - } , - - ], - "links" : [ - - { - "source" : ${link.from.sequence}, - "target" : ${link.to.sequence}, - "value" : ${link.histogram.totalCount}, - "error" : ${link.histogram.errorCount}, - "slow" : ${link.histogram.slowCount}, - "histogram" : ${link.histogram} - } , - - ] - } -} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/selectTransaction.jsp b/src/main/webapp/WEB-INF/views/transactionInfo.jsp similarity index 100% rename from src/main/webapp/WEB-INF/views/selectTransaction.jsp rename to src/main/webapp/WEB-INF/views/transactionInfo.jsp diff --git a/src/main/webapp/WEB-INF/views/requestmetadata.jsp b/src/main/webapp/WEB-INF/views/transactionmetadata.jsp similarity index 100% rename from src/main/webapp/WEB-INF/views/requestmetadata.jsp rename to src/main/webapp/WEB-INF/views/transactionmetadata.jsp diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 2805267db..64c7ca00e 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -59,8 +59,7 @@ NoCacheFilter - *.js - *.css + /* diff --git a/src/main/webapp/common/js/hippo/chart-scatter3.js b/src/main/webapp/common/js/hippo/chart-scatter3.js index d10a127c3..b26a90975 100644 --- a/src/main/webapp/common/js/hippo/chart-scatter3.js +++ b/src/main/webapp/common/js/hippo/chart-scatter3.js @@ -137,140 +137,6 @@ var selectDotCallback = function(traces) { var popupwindow = window.open("/selectedScatter.html", token); } -/* -var selectDotCallbackDeprecated = function(traces) { - if (traces.length === 0) { - return; - } - - if (traces.length === 1) { - openTrace(traces[0].traceId, traces[0].x); - return; - } - - var query = []; - var temp = {}; - for (var i = 0; i < traces.length; i++) { - if (i > 0) { - query.push("&"); - } - query.push("tr"); - query.push(i); - query.push("="); - query.push(traces[i].traceId); - - query.push("&ti"); - query.push(i); - query.push("="); - query.push(traces[i].x) - - query.push("&re"); - query.push(i); - query.push("="); - query.push(traces[i].y) - } - - $.post("/requestmetadata.hippo", query.join(""), function(d) { - $("#selectedBusinessTransactionsDetail TBODY").empty(); - - var data = jQuery.parseJSON(d).metadata; - - var html = []; - for (var i = 0; i < data.length; i++) { - - if(data[i].exception) { - html.push(""); - } else { - html.push(""); - } - - html.push(""); - html.push(i + 1); - html.push(""); - - html.push(""); - html.push(new Date(data[i].startTime).format("HH:MM:ss l")); - html.push(""); - - html.push(""); - html.push(""); - html.push(data[i].traceId); - html.push(""); - html.push(""); - - html.push(""); - html.push(formatNumber(data[i].elapsed)); - html.push(""); - - html.push(""); - if (data[i].exception) { - html.push(data[i].exception); - } - html.push(""); - - html.push(""); - html.push(data[i].application); - html.push(""); - - html.push(""); - html.push(data[i].agentId); - html.push(""); - - html.push(""); - html.push(""); - html.push(data[i].remoteAddr); - html.push(""); - html.push(""); - - html.push(""); - } - - $("#selectedBusinessTransactionsDetail TBODY").append(html.join('')); - $('#traceIdSelectModal').modal({}); - }) - .fail(function() { - alert("Failed to fetching the request informations."); - }); -} -*/ - -/* -var timer; -$("#auto_refresh").bind("change", function(){ - if (this.checked) { - if (timer != null) return; - - console.log("[auto-refresh] started.") - - clearInterval(timer); - setQueryDateToNow(); - updateCharts(); - - var from = getQueryEndTime(); - - timer = setInterval(function() { - setQueryDateToNow(); - console.log("[auto-refresh] fetching data from=" + from); - - getRealtimeScatterData(from, function(data) { - updateScatter(getQueryStartTime(), getQueryEndTime(), data.scatter, "#scatter"); - from = data.queryTo + 1; - }); - }, 3000); - } else { - clearInterval(timer); - timer = null; - console.log("[auto-refresh] stopped.") - } -}); -*/ - function updateScatter(start, end, scatter_data, targetId, limit) { if (scatter_data.length == 0) { return; diff --git a/src/main/webapp/common/js/hippo/hippo.js b/src/main/webapp/common/js/hippo/hippo.js index 134bf3bab..f4eec0cf2 100644 --- a/src/main/webapp/common/js/hippo/hippo.js +++ b/src/main/webapp/common/js/hippo/hippo.js @@ -3,7 +3,7 @@ function expandToNewWindow() { } function openTrace(uuid, timestamp) { - window.open("/selectTransaction.hippo?traceId=" + uuid + "&focusTimestamp=" + timestamp); + window.open("/transactionInfo.hippo?traceId=" + uuid + "&focusTimestamp=" + timestamp); } function getQueryPeriod() { diff --git a/src/main/webapp/index1.html b/src/main/webapp/index1.html deleted file mode 100644 index 38d4a699c..000000000 --- a/src/main/webapp/index1.html +++ /dev/null @@ -1,599 +0,0 @@ - - - - HIPPO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- THIS UI IS DEPRECATED. MOVE TO THE NEW UI Ver2. - - - -
-
- - -
-
- 박스나 연결선을 더블클릭하여 drill down. -
- -
-
-
-
- -
-
-


-
-
- -
-
- - -
-
-
-

-
-
- - - - - - - - - - - - -
NameCallsTime(ms)Min Time(ms)Max Time(ms)
- - - - - - - - - - - - -
#TimeTraceIdResponse Time (ms)
-
-
-
-
- - -
-
-
-
-
-
-
-
-
- - - - - - - \ No newline at end of file diff --git a/src/main/webapp/index2.html b/src/main/webapp/index2.html deleted file mode 100644 index 6d3c5af8f..000000000 --- a/src/main/webapp/index2.html +++ /dev/null @@ -1,580 +0,0 @@ - - - - HIPPO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
-
- THIS UI IS DEPRECATED. MOVE TO THE NEW UI Ver3. -
- -
-
- -
-
-
-

-
-
- - -
-
- - - - - - - - - - - - -
URLCallsTime(ms)Min Time(ms)Max Time(ms)
- - - - - - - - - - - - -
#TimeTraceIdResponse Time (ms)
-
-
-
-
- -
- - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/index3.html b/src/main/webapp/index3.html deleted file mode 100644 index 7268d3997..000000000 --- a/src/main/webapp/index3.html +++ /dev/null @@ -1,370 +0,0 @@ - - - - PROBE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
-
-
-
-
- -
-
-
- - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/selectedScatter.html b/src/main/webapp/selectedScatter.html index 352a6b926..bc162b7ba 100644 --- a/src/main/webapp/selectedScatter.html +++ b/src/main/webapp/selectedScatter.html @@ -131,7 +131,7 @@ $(document).ready(function () { query.push(traces[i].y) } - $.post("/requestmetadata.hippo", query.join(""), function(d) { + $.post("/transactionmetadata.hippo", query.join(""), function(d) { writeContents(d); $("#loader").hide(); }) @@ -165,7 +165,7 @@ var writeContents = function(d) { html.push(""); html.push(""); html.push(data[i].traceId); html.push("");