mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-29 06:36:46 +10:00
[유치수] [NOBTS] add terminal span
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@947 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -3,6 +3,7 @@ package com.nhn.hippo.web.calltree.server;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.nhn.hippo.web.vo.TerminalRequest;
|
||||
import com.profiler.common.ServiceType;
|
||||
import com.profiler.common.bo.SpanBo;
|
||||
|
||||
@@ -34,6 +35,13 @@ public class Server implements Comparable<Server> {
|
||||
this.serviceType = span.getServiceType();
|
||||
}
|
||||
|
||||
public Server(String id, String applicationName, String endPoint, ServiceType serviceType) {
|
||||
this.id = id;
|
||||
this.applicationName = applicationName;
|
||||
this.endPoint = endPoint;
|
||||
this.serviceType = serviceType;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@@ -3,49 +3,69 @@ package com.nhn.hippo.web.calltree.server;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
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 com.nhn.hippo.web.vo.BusinessTransactions;
|
||||
import com.profiler.common.bo.SpanBo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.nhn.hippo.web.vo.BusinessTransactions;
|
||||
import com.nhn.hippo.web.vo.TerminalRequest;
|
||||
import com.profiler.common.ServiceType;
|
||||
import com.profiler.common.bo.SpanBo;
|
||||
|
||||
/**
|
||||
* Call Tree
|
||||
*
|
||||
*
|
||||
* @author netspider
|
||||
*/
|
||||
public class ServerCallTree {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final String PREFIX_CLIENT = "CLIENT:";
|
||||
private final String PREFIX_CLIENT = "CLIENT:";
|
||||
|
||||
private final Map<String, Server> servers = new HashMap<String, Server>();
|
||||
private final Map<String, String> spanIdToServerId = new HashMap<String, String>();
|
||||
private final Map<String, ServerRequest> ServerRequests = new HashMap<String, ServerRequest>();
|
||||
private final List<SpanBo> spans = new ArrayList<SpanBo>();
|
||||
private final BusinessTransactions businessTransactions = new BusinessTransactions();
|
||||
private final Map<String, Server> servers = new HashMap<String, Server>();
|
||||
private final Map<String, String> spanIdToServerId = new HashMap<String, String>();
|
||||
private final Map<String, ServerRequest> serverRequests = new HashMap<String, ServerRequest>();
|
||||
private final List<SpanBo> spans = new ArrayList<SpanBo>();
|
||||
private final BusinessTransactions businessTransactions = new BusinessTransactions();
|
||||
|
||||
private boolean isBuilt = false;
|
||||
private boolean isBuilt = false;
|
||||
|
||||
private final Set<TerminalRequest> terminalRequests = new HashSet<TerminalRequest>();
|
||||
|
||||
public void addTerminal(TerminalRequest terminal) {
|
||||
terminalRequests.add(terminal);
|
||||
|
||||
// Server server = new Server(terminal.getTo(), terminal.getTo(), "UNKNOWN", ServiceType.parse(terminal.getToServiceType()));
|
||||
// servers.put(server.getId(), server);
|
||||
//
|
||||
// Server from = new Server(terminal.getFrom(), terminal.getFrom(), "UNKNOWN", ServiceType.UNKNOWN);
|
||||
//
|
||||
// ServerRequest request = new ServerRequest(from, server);
|
||||
// serverRequests.put(request.getId(), request);
|
||||
}
|
||||
|
||||
public void addSpan(SpanBo span) {
|
||||
/**
|
||||
* make Servers
|
||||
*/
|
||||
// TODO: 여기에서 이러지말고 수집할 때 처음부터 table에 저장해둘 수 있나??
|
||||
Server server = new Server(span);
|
||||
public void addSpan(SpanBo span) {
|
||||
/**
|
||||
* make Servers
|
||||
*/
|
||||
// TODO: 여기에서 이러지말고 수집할 때 처음부터 table에 저장해둘 수 있나??
|
||||
Server server = new Server(span);
|
||||
|
||||
if (server.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: remove this later.
|
||||
// if (server.getId().contains("mysql:jdbc:") || server.getId().contains("favicon")) {
|
||||
// return;
|
||||
// }
|
||||
if (server.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: remove this later.
|
||||
// if (server.getId().contains("mysql:jdbc:") ||
|
||||
// server.getId().contains("favicon")) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!servers.containsKey(server.getId())) {
|
||||
servers.put(server.getId(), server);
|
||||
@@ -54,86 +74,102 @@ public class ServerCallTree {
|
||||
}
|
||||
spanIdToServerId.put(String.valueOf(span.getSpanId()), server.getId());
|
||||
|
||||
// TODO: remove client node
|
||||
// if (span.getParentSpanId() == -1) {
|
||||
// Server client = new Server(PREFIX_CLIENT + span.getAgentID(), span.getEndPoint(), false);
|
||||
// servers.put(client.getId(), client);
|
||||
// spanIdToServerId.put(PREFIX_CLIENT + span.getSpanID(), client.getId());
|
||||
// }
|
||||
// TODO: remove client node
|
||||
// if (span.getParentSpanId() == -1) {
|
||||
// Server client = new Server(PREFIX_CLIENT + span.getAgentID(),
|
||||
// span.getEndPoint(), false);
|
||||
// servers.put(client.getId(), client);
|
||||
// spanIdToServerId.put(PREFIX_CLIENT + span.getSpanID(),
|
||||
// client.getId());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Preparing makes link (ServerRequests)
|
||||
*/
|
||||
if (span.getParentSpanId() == -1) {
|
||||
businessTransactions.add(span);
|
||||
} else {
|
||||
spans.add(span);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Preparing makes link (ServerRequests)
|
||||
*/
|
||||
if (span.getParentSpanId() == -1) {
|
||||
businessTransactions.add(span);
|
||||
} else {
|
||||
spans.add(span);
|
||||
}
|
||||
}
|
||||
|
||||
public ServerCallTree build() {
|
||||
if (isBuilt)
|
||||
return this;
|
||||
public ServerCallTree build() {
|
||||
if (isBuilt)
|
||||
return this;
|
||||
|
||||
int i = 0;
|
||||
for (Entry<String, Server> entry : servers.entrySet()) {
|
||||
entry.getValue().setSequence(i++);
|
||||
}
|
||||
// add terminal servers
|
||||
for (TerminalRequest terminal : terminalRequests) {
|
||||
Server server = new Server(terminal.getTo(), terminal.getTo(), "UNKNOWN", ServiceType.parse(terminal.getToServiceType()));
|
||||
servers.put(server.getId(), server);
|
||||
}
|
||||
|
||||
// mark server index
|
||||
int i = 0;
|
||||
for (Entry<String, Server> entry : servers.entrySet()) {
|
||||
entry.getValue().setSequence(i++);
|
||||
}
|
||||
|
||||
for (SpanBo span : spans) {
|
||||
String from = String.valueOf(span.getParentSpanId());
|
||||
String to = String.valueOf(span.getSpanId());
|
||||
// add terminal requests
|
||||
for (TerminalRequest terminal : terminalRequests) {
|
||||
ServerRequest request = new ServerRequest(servers.get(terminal.getFrom()), servers.get(terminal.getTo()));
|
||||
serverRequests.put(request.getId(), request);
|
||||
}
|
||||
|
||||
// add non-terminal requests
|
||||
for (SpanBo span : spans) {
|
||||
String from = String.valueOf(span.getParentSpanId());
|
||||
String to = String.valueOf(span.getSpanId());
|
||||
|
||||
Server fromServer = servers.get(spanIdToServerId.get(from));
|
||||
Server toServer = servers.get(spanIdToServerId.get(to));
|
||||
Server fromServer = servers.get(spanIdToServerId.get(from));
|
||||
Server toServer = servers.get(spanIdToServerId.get(to));
|
||||
|
||||
if (fromServer == null) {
|
||||
fromServer = servers.get(spanIdToServerId.get(PREFIX_CLIENT + to));
|
||||
}
|
||||
if (fromServer == null) {
|
||||
fromServer = servers.get(spanIdToServerId.get(PREFIX_CLIENT + to));
|
||||
}
|
||||
|
||||
// TODO 없는 url에 대한 호출이 고려되어야 함. 일단 임시로 회피.
|
||||
if (fromServer == null) {
|
||||
logger.debug("invalid form server {}", from);
|
||||
continue;
|
||||
}
|
||||
ServerRequest serverRequest = new ServerRequest(fromServer, toServer);
|
||||
// TODO 없는 url에 대한 호출이 고려되어야 함. 일단 임시로 회피.
|
||||
if (fromServer == null) {
|
||||
logger.debug("invalid form server {}", from);
|
||||
continue;
|
||||
}
|
||||
ServerRequest serverRequest = new ServerRequest(fromServer, toServer);
|
||||
|
||||
// TODO: local call인 경우 보여주지 않음.
|
||||
if (serverRequest.isSelfCalled()) {
|
||||
continue;
|
||||
}
|
||||
// TODO: local call인 경우 보여주지 않음.
|
||||
if (serverRequest.isSelfCalled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ServerRequests.containsKey(serverRequest.getId())) {
|
||||
ServerRequests.get(serverRequest.getId()).addRequest(span.getElapsed());
|
||||
} else {
|
||||
ServerRequests.put(serverRequest.getId(), serverRequest);
|
||||
}
|
||||
}
|
||||
if (serverRequests.containsKey(serverRequest.getId())) {
|
||||
serverRequests.get(serverRequest.getId()).addRequest(span.getElapsed());
|
||||
} else {
|
||||
serverRequests.put(serverRequest.getId(), serverRequest);
|
||||
}
|
||||
}
|
||||
|
||||
isBuilt = true;
|
||||
return this;
|
||||
}
|
||||
isBuilt = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Collection<Server> getNodes() {
|
||||
return this.servers.values();
|
||||
}
|
||||
public Collection<Server> getNodes() {
|
||||
return this.servers.values();
|
||||
}
|
||||
|
||||
public Collection<ServerRequest> getLinks() {
|
||||
return this.ServerRequests.values();
|
||||
}
|
||||
public Collection<ServerRequest> getLinks() {
|
||||
return this.serverRequests.values();
|
||||
}
|
||||
|
||||
public BusinessTransactions getBusinessTransactions() {
|
||||
return businessTransactions;
|
||||
}
|
||||
public BusinessTransactions getBusinessTransactions() {
|
||||
return businessTransactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("Server=").append(servers);
|
||||
sb.append("\n");
|
||||
sb.append("ServerRequest=").append(ServerRequests.values());
|
||||
sb.append("Server=").append(servers);
|
||||
sb.append("\n");
|
||||
sb.append("ServerRequest=").append(serverRequests.values());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.nhn.hippo.web.controller;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -14,7 +12,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.nhn.hippo.web.calltree.rpc.RPCCallTree;
|
||||
import com.nhn.hippo.web.calltree.server.ServerCallTree;
|
||||
import com.nhn.hippo.web.calltree.span.SpanAlign;
|
||||
import com.nhn.hippo.web.service.FlowChartService;
|
||||
@@ -44,15 +41,11 @@ public class BusinessTransactionController {
|
||||
mv.addObject("spanList", spanAligns);
|
||||
mv.addObject("traceId", traceId);
|
||||
|
||||
Set<TraceId> traceIds = new HashSet<TraceId>(1);
|
||||
traceIds.add(new TraceId(UUID.fromString(traceId)));
|
||||
ServerCallTree callTree = flow.selectServerCallTree(traceIds);
|
||||
// Set<TraceId> traceIds = new HashSet<TraceId>(1);
|
||||
// traceIds.add(new TraceId(UUID.fromString(traceId)));
|
||||
ServerCallTree callTree = flow.selectServerCallTree(new TraceId(UUID.fromString(traceId)));
|
||||
mv.addObject("nodes", callTree.getNodes());
|
||||
mv.addObject("links", callTree.getLinks());
|
||||
|
||||
RPCCallTree rpcTree = flow.selectRPCCallTree(traceIds);
|
||||
mv.addObject("rpcnodes", rpcTree.getNodes());
|
||||
mv.addObject("rpclinks", rpcTree.getLinks());
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ public class FlowChartController {
|
||||
Set<TraceId> traceIds = flow.selectTraceIdsFromApplicationTraceIndex(applicationName, from, to);
|
||||
|
||||
watch.stop();
|
||||
logger.info("time:{} {}", watch.getLastTaskTimeMillis(), traceIds.size());
|
||||
logger.info("Fetch traceIds elapsed : {}ms, {} traces", watch.getLastTaskTimeMillis(), traceIds.size());
|
||||
watch.start("selectServerCallTree");
|
||||
|
||||
ServerCallTree callTree = flow.selectServerCallTree(traceIds);
|
||||
ServerCallTree callTree = flow.selectServerCallTree(traceIds, applicationName, from, to);
|
||||
|
||||
watch.stop();
|
||||
logger.info("time:{}", watch.getLastTaskTimeMillis());
|
||||
logger.info("Fetch calltree time : {}ms", watch.getLastTaskTimeMillis());
|
||||
|
||||
model.addAttribute("nodes", callTree.getNodes());
|
||||
model.addAttribute("links", callTree.getLinks());
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.nhn.hippo.web.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.nhn.hippo.web.vo.TerminalRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public interface TerminalStatisticsDao {
|
||||
public List<List<TerminalRequest>> selectTerminal(String applicationName, long from, long to);
|
||||
}
|
||||
@@ -18,11 +18,13 @@ public interface TraceDao {
|
||||
List<SpanBo> selectSpanAndAnnotation(UUID traceId);
|
||||
|
||||
List<SpanBo> selectSpan(long traceIdMost, long traceIdLeast);
|
||||
|
||||
|
||||
List<List<SpanBo>> selectSpans(List<UUID> traceIds);
|
||||
|
||||
List<List<SpanBo>> selectSpans(Set<TraceId> traceIds);
|
||||
|
||||
List<SpanBo> selectSpans(TraceId traceId);
|
||||
|
||||
@Deprecated
|
||||
List<List<SpanBo>> selectSpansAndAnnotation(Set<TraceId> traceIds);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.nhn.hippo.web.dao.hbase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hadoop.hbase.client.Scan;
|
||||
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.TerminalRequest;
|
||||
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
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public class HbaseTerminalStatisticsDao implements TerminalStatisticsDao {
|
||||
|
||||
private int scanCacheSize = 40;
|
||||
|
||||
@Autowired
|
||||
private HbaseOperations2 hbaseOperations2;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("terminalRequestCountMapper")
|
||||
private RowMapper<List<TerminalRequest>> terminalRequestCountMapper;
|
||||
|
||||
@Override
|
||||
public List<List<TerminalRequest>> selectTerminal(String applicationName, long from, long to) {
|
||||
Scan scan = createScan(applicationName, from, to);
|
||||
return hbaseOperations2.find(HBaseTables.TERMINAL_STATISTICS, scan, terminalRequestCountMapper);
|
||||
}
|
||||
|
||||
private Scan createScan(String applicationName, long from, long to) {
|
||||
byte[] startKey = TerminalSpanUtils.makeRowKey(applicationName, TimeSlot.getSlot(from));
|
||||
byte[] endKey = TerminalSpanUtils.makeRowKey(applicationName, TimeSlot.getSlot(to));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,8 @@ import com.profiler.common.util.BytesUtils;
|
||||
public class HbaseTraceDao implements TraceDao {
|
||||
|
||||
private final byte[] COLFAM_SPAN = HBaseTables.TRACES_CF_SPAN;
|
||||
|
||||
private final byte[] COLFAM_TERMINALSPAN = HBaseTables.TRACES_CF_TERMINALSPAN;
|
||||
|
||||
private final byte[] COLFAM_ANNOTATION = HBaseTables.TRACES_CF_ANNOTATION;
|
||||
|
||||
@@ -54,6 +56,7 @@ public class HbaseTraceDao implements TraceDao {
|
||||
Get get = new Get(uuidBytes);
|
||||
get.addFamily(COLFAM_SPAN);
|
||||
get.addFamily(COLFAM_ANNOTATION);
|
||||
get.addFamily(COLFAM_TERMINALSPAN);
|
||||
return template2.get(HBaseTables.TRACES, get, spanAnnotationMapper);
|
||||
}
|
||||
|
||||
@@ -85,6 +88,14 @@ public class HbaseTraceDao implements TraceDao {
|
||||
}
|
||||
return template2.get(HBaseTables.TRACES, gets, spanMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpans(TraceId traceId) {
|
||||
Get get = new Get(traceId.getBytes());
|
||||
get.addFamily(COLFAM_SPAN);
|
||||
get.addFamily(COLFAM_TERMINALSPAN);
|
||||
return template2.get(HBaseTables.TRACES, get, spanMapper);
|
||||
}
|
||||
|
||||
public List<List<SpanBo>> selectSpansAndAnnotation(Set<TraceId> traceIds) {
|
||||
List<Get> gets = new ArrayList<Get>(traceIds.size());
|
||||
|
||||
@@ -51,7 +51,8 @@ public class SpanMapper implements RowMapper<List<SpanBo>> {
|
||||
List<SpanBo> spanList = new ArrayList<SpanBo>();
|
||||
for (KeyValue kv : keyList) {
|
||||
// family name "span"일때로만 한정.
|
||||
if (kv.getFamilyLength() == HBaseTables.TRACES_CF_SPAN.length) {
|
||||
if (kv.getFamilyLength() == HBaseTables.TRACES_CF_SPAN.length ||
|
||||
kv.getFamilyLength() == HBaseTables.TRACES_CF_TERMINALSPAN.length) {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setMostTraceId(most);
|
||||
spanBo.setLeastTraceId(least);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.nhn.hippo.web.mapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.TerminalRequest;
|
||||
import com.profiler.common.hbase.HBaseTables;
|
||||
import com.profiler.common.util.TerminalSpanUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class TerminalRequestCountMapper implements RowMapper<List<TerminalRequest>> {
|
||||
|
||||
@Override
|
||||
public List<TerminalRequest> mapRow(Result result, int rowNum) throws Exception {
|
||||
KeyValue[] keyList = result.raw();
|
||||
|
||||
List<TerminalRequest> requestList = new ArrayList<TerminalRequest>();
|
||||
for (KeyValue kv : keyList) {
|
||||
if (kv.getFamilyLength() == HBaseTables.TERMINAL_STATISTICS_CF_COUNTER.length) {
|
||||
String from = TerminalSpanUtils.getApplicationNameFromRowKey(kv.getRow());
|
||||
String to = TerminalSpanUtils.getApplicationNameFromColumnName(kv.getQualifier());
|
||||
int requestCount = Bytes.toInt(kv.getValue());
|
||||
short serviceType = TerminalSpanUtils.getServiceTypeFromColumnName(kv.getQualifier());
|
||||
|
||||
TerminalRequest request = new TerminalRequest(from, to, serviceType, requestCount);
|
||||
requestList.add(request);
|
||||
}
|
||||
}
|
||||
return requestList;
|
||||
}
|
||||
}
|
||||
@@ -56,14 +56,24 @@ public interface FlowChartService {
|
||||
*/
|
||||
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param traceIds
|
||||
* @param applicationName
|
||||
* @param from
|
||||
* @param to
|
||||
* @return
|
||||
*/
|
||||
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds, String applicationName, long from, long to);
|
||||
|
||||
/**
|
||||
* select all application names
|
||||
*
|
||||
* @return all of application names
|
||||
*/
|
||||
public List<String> selectAllApplicationNames();
|
||||
|
||||
|
||||
public String[] selectAgentIds(String[] hosts);
|
||||
|
||||
public String[] selectAgentIds(String[] hosts);
|
||||
|
||||
public ServerCallTree selectServerCallTree(TraceId traceId);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.nhn.hippo.web.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -12,14 +14,17 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import com.nhn.hippo.web.calltree.rpc.RPCCallTree;
|
||||
import com.nhn.hippo.web.calltree.server.ServerCallTree;
|
||||
import com.nhn.hippo.web.dao.ApplicationIndexDao;
|
||||
import com.nhn.hippo.web.dao.ApplicationTraceIndexDao;
|
||||
import com.nhn.hippo.web.dao.RootTraceIndexDao;
|
||||
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.TerminalRequest;
|
||||
import com.nhn.hippo.web.vo.TraceId;
|
||||
import com.profiler.common.ServiceType;
|
||||
import com.profiler.common.bo.SpanBo;
|
||||
@@ -34,96 +39,169 @@ import com.profiler.common.hbase.HBaseTables;
|
||||
@Service
|
||||
public class FlowChartServiceImpl implements FlowChartService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseClient")
|
||||
HBaseClient client;
|
||||
@Autowired
|
||||
@Qualifier("hbaseClient")
|
||||
HBaseClient client;
|
||||
|
||||
@Autowired
|
||||
private TraceDao traceDao;
|
||||
@Autowired
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Autowired
|
||||
private RootTraceIndexDao rootTraceIndexDao;
|
||||
@Autowired
|
||||
private RootTraceIndexDao rootTraceIndexDao;
|
||||
|
||||
@Autowired
|
||||
private TraceIndexDao traceIndexDao;
|
||||
@Autowired
|
||||
private TraceIndexDao traceIndexDao;
|
||||
|
||||
@Autowired
|
||||
private ApplicationIndexDao applicationIndexDao;
|
||||
@Autowired
|
||||
private ApplicationIndexDao applicationIndexDao;
|
||||
|
||||
@Autowired
|
||||
private ApplicationTraceIndexDao applicationTraceIndexDao;
|
||||
@Autowired
|
||||
private ApplicationTraceIndexDao applicationTraceIndexDao;
|
||||
|
||||
@Override
|
||||
public List<String> selectAllApplicationNames() {
|
||||
return applicationIndexDao.selectAllApplicationNames();
|
||||
}
|
||||
@Autowired
|
||||
private TerminalStatisticsDao terminalStatisticsDao;
|
||||
|
||||
@Override
|
||||
public String[] selectAgentIdsFromApplicationName(String applicationName) {
|
||||
return applicationIndexDao.selectAgentIds(applicationName);
|
||||
}
|
||||
@Override
|
||||
public List<String> selectAllApplicationNames() {
|
||||
return applicationIndexDao.selectAllApplicationNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TraceId> selectTraceIdsFromTraceIndex(String[] agentIds, long from, long to) {
|
||||
if (agentIds == null) {
|
||||
throw new NullPointerException("agentIds");
|
||||
}
|
||||
@Override
|
||||
public String[] selectAgentIdsFromApplicationName(String applicationName) {
|
||||
return applicationIndexDao.selectAgentIds(applicationName);
|
||||
}
|
||||
|
||||
if (agentIds.length == 1) {
|
||||
// single scan
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("scan {}, {}, {}", new Object[]{agentIds[0], from, to});
|
||||
}
|
||||
List<byte[]> bytes = this.traceIndexDao.scanTraceIndex(agentIds[0], from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (byte[] traceId : bytes) {
|
||||
TraceId tid = new TraceId(traceId);
|
||||
result.add(tid);
|
||||
logger.trace("traceid:{}", tid);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
// multi scan 가능한 동일 open htable 에서 액세스함.
|
||||
List<List<byte[]>> multiScan = this.traceIndexDao.multiScanTraceIndex(agentIds, from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (List<byte[]> scan : multiScan) {
|
||||
for (byte[] traceId : scan) {
|
||||
result.add(new TraceId(traceId));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Set<TraceId> selectTraceIdsFromTraceIndex(String[] agentIds, long from, long to) {
|
||||
if (agentIds == null) {
|
||||
throw new NullPointerException("agentIds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCCallTree selectRPCCallTree(Set<TraceId> traceIds) {
|
||||
final RPCCallTree tree = new RPCCallTree();
|
||||
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
|
||||
for (List<SpanBo> transaction : traces) {
|
||||
for (SpanBo eachTransaction : transaction) {
|
||||
tree.addSpan(eachTransaction);
|
||||
}
|
||||
}
|
||||
return tree.build();
|
||||
}
|
||||
if (agentIds.length == 1) {
|
||||
// single scan
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("scan {}, {}, {}", new Object[] { agentIds[0], from, to });
|
||||
}
|
||||
List<byte[]> bytes = this.traceIndexDao.scanTraceIndex(agentIds[0], from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (byte[] traceId : bytes) {
|
||||
TraceId tid = new TraceId(traceId);
|
||||
result.add(tid);
|
||||
logger.trace("traceid:{}", tid);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
// multi scan 가능한 동일 open htable 에서 액세스함.
|
||||
List<List<byte[]>> multiScan = this.traceIndexDao.multiScanTraceIndex(agentIds, from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (List<byte[]> scan : multiScan) {
|
||||
for (byte[] traceId : scan) {
|
||||
result.add(new TraceId(traceId));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds) {
|
||||
final ServerCallTree tree = new ServerCallTree();
|
||||
@Override
|
||||
public RPCCallTree selectRPCCallTree(Set<TraceId> traceIds) {
|
||||
final RPCCallTree tree = new RPCCallTree();
|
||||
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
|
||||
for (List<SpanBo> transaction : traces) {
|
||||
for (SpanBo eachTransaction : transaction) {
|
||||
tree.addSpan(eachTransaction);
|
||||
}
|
||||
}
|
||||
return tree.build();
|
||||
}
|
||||
|
||||
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
|
||||
@Override
|
||||
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds) {
|
||||
final ServerCallTree tree = new ServerCallTree();
|
||||
|
||||
for (List<SpanBo> transaction : traces) {
|
||||
List<SpanBo> processed = refine(transaction);
|
||||
markRecursiveCall(processed);
|
||||
for (SpanBo eachTransaction : processed) {
|
||||
tree.addSpan(eachTransaction);
|
||||
}
|
||||
}
|
||||
return tree.build();
|
||||
}
|
||||
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
|
||||
|
||||
for (List<SpanBo> transaction : traces) {
|
||||
List<SpanBo> processed = refine(transaction);
|
||||
markRecursiveCall(processed);
|
||||
for (SpanBo eachTransaction : processed) {
|
||||
tree.addSpan(eachTransaction);
|
||||
}
|
||||
}
|
||||
return tree.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerCallTree selectServerCallTree(TraceId traceId) {
|
||||
final ServerCallTree tree = new ServerCallTree();
|
||||
|
||||
List<SpanBo> transaction = this.traceDao.selectSpans(traceId);
|
||||
|
||||
List<SpanBo> processed = refine(transaction);
|
||||
markRecursiveCall(processed);
|
||||
for (SpanBo eachTransaction : processed) {
|
||||
tree.addSpan(eachTransaction);
|
||||
}
|
||||
return tree.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds, String applicationName, long from, long to) {
|
||||
final Map<String, ServiceType> terminalQueryParams = new HashMap<String, ServiceType>();
|
||||
final ServerCallTree tree = new ServerCallTree();
|
||||
|
||||
StopWatch watch = new StopWatch();
|
||||
watch.start("scanNonTerminalSpans");
|
||||
|
||||
// fetch non-terminal spans
|
||||
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
|
||||
|
||||
watch.stop();
|
||||
int totalNonTerminalSpansCount = 0;
|
||||
|
||||
// processing spans
|
||||
for (List<SpanBo> transaction : traces) {
|
||||
totalNonTerminalSpansCount += transaction.size();
|
||||
|
||||
List<SpanBo> processed = refine(transaction);
|
||||
markRecursiveCall(processed);
|
||||
for (SpanBo eachTransaction : processed) {
|
||||
tree.addSpan(eachTransaction);
|
||||
|
||||
// make query param
|
||||
terminalQueryParams.put(eachTransaction.getServiceName(), eachTransaction.getServiceType());
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Fetch non-terminal spans elapsed : {}ms, {} traces, {} spans", new Object[] { watch.getLastTaskTimeMillis(), traces.size(), totalNonTerminalSpansCount });
|
||||
}
|
||||
|
||||
watch.start("scanTerminalStatistics");
|
||||
|
||||
// fetch terminal info
|
||||
for (Entry<String, ServiceType> param : terminalQueryParams.entrySet()) {
|
||||
ServiceType svcType = param.getValue();
|
||||
if (!svcType.isRpcClient() && !svcType.isUnknown() && !svcType.isTerminal()) {
|
||||
long start = System.currentTimeMillis();
|
||||
List<List<TerminalRequest>> terminals = terminalStatisticsDao.selectTerminal(param.getKey(), from, to);
|
||||
logger.info(" Fetch terminals of {} : {}ms", param.getKey(), System.currentTimeMillis() - start);
|
||||
|
||||
for (List<TerminalRequest> terminal : terminals) {
|
||||
for (TerminalRequest t : terminal) {
|
||||
tree.addTerminal(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch.stop();
|
||||
logger.info("Fetch terminal statistics elapsed : {}ms", watch.getLastTaskTimeMillis());
|
||||
|
||||
return tree.build();
|
||||
}
|
||||
|
||||
private SpanBo findChildSpan(final List<SpanBo> list, final SpanBo parent) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
@@ -139,10 +217,7 @@ public class FlowChartServiceImpl implements FlowChartService {
|
||||
private List<SpanBo> refine(final List<SpanBo> list) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
SpanBo span = list.get(i);
|
||||
String svcName = span.getServiceName();
|
||||
|
||||
// TODO 임시로 HTTP/1.1을 확인하게 해두었음. merge해야하는 span 확인 방법을 바꿔야함.
|
||||
// if ("HTTP/1.1".equals(svcName)) {
|
||||
if (span.getServiceType().isRpcClient()) {
|
||||
SpanBo child = findChildSpan(list, span);
|
||||
|
||||
@@ -161,58 +236,58 @@ public class FlowChartServiceImpl implements FlowChartService {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void markRecursiveCall(final List<SpanBo> 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<TraceId> selectTraceIdsFromApplicationTraceIndex(String applicationName, long from, long to) {
|
||||
if (applicationName == null) {
|
||||
throw new NullPointerException("applicationName");
|
||||
}
|
||||
private void markRecursiveCall(final List<SpanBo> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("scan {}, {}, {}", new Object[]{applicationName, from, to});
|
||||
}
|
||||
@Override
|
||||
public Set<TraceId> selectTraceIdsFromApplicationTraceIndex(String applicationName, long from, long to) {
|
||||
if (applicationName == null) {
|
||||
throw new NullPointerException("applicationName");
|
||||
}
|
||||
|
||||
List<byte[]> bytes = this.applicationTraceIndexDao.scanTraceIndex(applicationName, from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (byte[] traceId : bytes) {
|
||||
TraceId tid = new TraceId(traceId);
|
||||
result.add(tid);
|
||||
logger.trace("traceid:{}", tid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("scan {}, {}, {}", new Object[] { applicationName, from, to });
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] selectAgentIds(String[] hosts) {
|
||||
List<HbaseColumn> column = new ArrayList<HBaseQuery.HbaseColumn>();
|
||||
column.add(new HbaseColumn("Agents", "AgentID"));
|
||||
List<byte[]> bytes = this.applicationTraceIndexDao.scanTraceIndex(applicationName, from, to);
|
||||
Set<TraceId> result = new HashSet<TraceId>();
|
||||
for (byte[] traceId : bytes) {
|
||||
TraceId tid = new TraceId(traceId);
|
||||
result.add(tid);
|
||||
logger.trace("traceid:{}", tid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HBaseQuery query = new HBaseQuery(HBaseTables.APPLICATION_INDEX, null, null, column);
|
||||
Iterator<Map<String, byte[]>> iterator = client.getHBaseData(query);
|
||||
@Override
|
||||
public String[] selectAgentIds(String[] hosts) {
|
||||
List<HbaseColumn> column = new ArrayList<HBaseQuery.HbaseColumn>();
|
||||
column.add(new HbaseColumn("Agents", "AgentID"));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
while (iterator.hasNext()) {
|
||||
logger.debug("selectedAgentId={}", iterator.next());
|
||||
}
|
||||
logger.debug("!!!==============WARNING==============!!!");
|
||||
logger.debug("!!! selectAgentIds IS NOT IMPLEMENTED !!!");
|
||||
logger.debug("!!!===================================!!!");
|
||||
}
|
||||
HBaseQuery query = new HBaseQuery(HBaseTables.APPLICATION_INDEX, null, null, column);
|
||||
Iterator<Map<String, byte[]>> iterator = client.getHBaseData(query);
|
||||
|
||||
return hosts;
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
while (iterator.hasNext()) {
|
||||
logger.debug("selectedAgentId={}", iterator.next());
|
||||
}
|
||||
logger.debug("!!!==============WARNING==============!!!");
|
||||
logger.debug("!!! selectAgentIds IS NOT IMPLEMENTED !!!");
|
||||
logger.debug("!!!===================================!!!");
|
||||
}
|
||||
|
||||
return hosts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
package com.nhn.hippo.web.service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.nhn.hippo.web.calltree.span.SpanAlign;
|
||||
import com.nhn.hippo.web.calltree.span.SpanAligner;
|
||||
import com.nhn.hippo.web.dao.TraceDao;
|
||||
@@ -8,14 +17,6 @@ import com.profiler.common.bo.SpanBo;
|
||||
import com.profiler.common.mapping.ApiMappingTable;
|
||||
import com.profiler.common.mapping.ApiUtils;
|
||||
import com.profiler.common.mapping.MethodMapping;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -23,59 +24,61 @@ import java.util.UUID;
|
||||
@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;
|
||||
|
||||
@Override
|
||||
public List<SpanAlign> selectSpan(String uuid) {
|
||||
UUID id = UUID.fromString(uuid);
|
||||
List<SpanBo> spans = traceDao.selectSpanAndAnnotation(id);
|
||||
if (spans == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
transitionApiId(spans);
|
||||
List<SpanAlign> order = order(spans);
|
||||
// TODO root span not found시 row data라도 보여줘야 됨.
|
||||
if (order.size() != spans.size()) {
|
||||
// TODO 중간 노드 데이터 분실 ? 혹은 잘못된 데이터 생성?
|
||||
logger.info("span node not complete! ");
|
||||
}
|
||||
return order;
|
||||
@Override
|
||||
public List<SpanAlign> selectSpan(String uuid) {
|
||||
UUID id = UUID.fromString(uuid);
|
||||
List<SpanBo> spans = traceDao.selectSpanAndAnnotation(id);
|
||||
if (spans == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
transitionApiId(spans);
|
||||
List<SpanAlign> order = order(spans);
|
||||
// TODO root span not found시 row data라도 보여줘야 됨.
|
||||
if (order.size() != spans.size()) {
|
||||
// TODO 중간 노드 데이터 분실 ? 혹은 잘못된 데이터 생성?
|
||||
logger.info("span node not complete! ");
|
||||
}
|
||||
return order;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void transitionApiId(List<SpanBo> spans) {
|
||||
for (SpanBo spanBo : spans) {
|
||||
List<AnnotationBo> annotationBoList = spanBo.getAnnotationBoList();
|
||||
for (AnnotationBo annotationBo : annotationBoList) {
|
||||
// TODO API-ID 일단 날코딩 나중에 뭔가 key를 따자
|
||||
if ("API-ID".equals(annotationBo.getKey())) {
|
||||
MethodMapping methodMapping = null;
|
||||
try {
|
||||
methodMapping = ApiMappingTable.findMethodMapping((Integer) annotationBo.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
}
|
||||
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("API");
|
||||
api.setValue(className + "." + methodName + args);
|
||||
annotationBoList.add(api);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void transitionApiId(List<SpanBo> spans) {
|
||||
for (SpanBo spanBo : spans) {
|
||||
List<AnnotationBo> annotationBoList = spanBo.getAnnotationBoList();
|
||||
for (AnnotationBo annotationBo : annotationBoList) {
|
||||
// TODO API-ID 일단 날코딩 나중에 뭔가 key를 따자
|
||||
if ("API-ID".equals(annotationBo.getKey())) {
|
||||
MethodMapping methodMapping = null;
|
||||
try {
|
||||
methodMapping = ApiMappingTable.findMethodMapping((Integer) annotationBo.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // To change body of catch
|
||||
// statement use File | Settings
|
||||
// | File Templates.
|
||||
}
|
||||
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("API");
|
||||
api.setValue(className + "." + methodName + args);
|
||||
annotationBoList.add(api);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<SpanAlign> order(List<SpanBo> spans) {
|
||||
private List<SpanAlign> order(List<SpanBo> spans) {
|
||||
|
||||
SpanAligner spanAligner = new SpanAligner(spans);
|
||||
return spanAligner.sort();
|
||||
}
|
||||
SpanAligner spanAligner = new SpanAligner(spans);
|
||||
return spanAligner.sort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.nhn.hippo.web.vo;
|
||||
|
||||
public class TerminalRequest {
|
||||
|
||||
private final String from;
|
||||
private final String to;
|
||||
private final short toServiceType;
|
||||
private final int requestCount;
|
||||
|
||||
public TerminalRequest(String from, String to, short toServiceType, int requestCount) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.toServiceType = toServiceType;
|
||||
this.requestCount = requestCount;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public int getRequestCount() {
|
||||
return requestCount;
|
||||
}
|
||||
|
||||
public short getToServiceType() {
|
||||
return toServiceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{From=" + from + ", To=" + to + ", ReqCount=" + requestCount + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((from == null) ? 0 : from.hashCode());
|
||||
result = prime * result + requestCount;
|
||||
result = prime * result + ((to == null) ? 0 : to.hashCode());
|
||||
result = prime * result + toServiceType;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TerminalRequest other = (TerminalRequest) obj;
|
||||
if (from == null) {
|
||||
if (other.from != null)
|
||||
return false;
|
||||
} else if (!from.equals(other.from))
|
||||
return false;
|
||||
if (requestCount != other.requestCount)
|
||||
return false;
|
||||
if (to == null) {
|
||||
if (other.to != null)
|
||||
return false;
|
||||
} else if (!to.equals(other.to))
|
||||
return false;
|
||||
if (toServiceType != other.toServiceType)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -23,4 +23,5 @@
|
||||
</bean>
|
||||
<bean id="applicationNameMapper" class="com.nhn.hippo.web.mapper.ApplicationNameMapper"></bean>
|
||||
<bean id="agentIdMapper" class="com.nhn.hippo.web.mapper.AgentIdMapper"></bean>
|
||||
<bean id="terminalRequestCountMapper" class="com.nhn.hippo.web.mapper.TerminalRequestCountMapper"></bean>
|
||||
</beans>
|
||||
|
||||
@@ -15,19 +15,17 @@
|
||||
],
|
||||
"serviceType" : "${node.serviceType}",
|
||||
"terminal" : "${node.serviceType.terminal}"
|
||||
}
|
||||
<c:if test="${!status.last}">,</c:if>
|
||||
} <c:if test="${!status.last}">,</c:if>
|
||||
</c:forEach>
|
||||
],
|
||||
"links" : [
|
||||
<c:forEach items="${links}" var="link" varStatus="status">
|
||||
{
|
||||
"source" : ${link.from.sequence},
|
||||
"source" : ${link.from.sequence},
|
||||
"target" : ${link.to.sequence},
|
||||
"value" : ${link.histogram.sampleCount},
|
||||
"histogram" : ${link.histogram}
|
||||
}
|
||||
<c:if test="${!status.last}">,</c:if>
|
||||
"histogram" : ${link.histogram}
|
||||
} <c:if test="${!status.last}">,</c:if>
|
||||
</c:forEach>
|
||||
]
|
||||
},
|
||||
@@ -47,8 +45,7 @@
|
||||
<c:if test="${!status2.last}">,</c:if>
|
||||
</c:forEach>
|
||||
]
|
||||
}
|
||||
<c:if test="${!status.last}">,</c:if>
|
||||
} <c:if test="${!status.last}">,</c:if>
|
||||
</c:forEach>
|
||||
],
|
||||
|
||||
@@ -60,8 +57,7 @@
|
||||
"timestamp" : ${trace.startTime},
|
||||
"executionTime" : ${trace.executionTime},
|
||||
"name" : "${t.rpc}"
|
||||
}
|
||||
<c:if test="${!status4.last}">,</c:if>
|
||||
} <c:if test="${!status4.last}">,</c:if>
|
||||
</c:forEach>
|
||||
<c:if test="${!status3.last}">,</c:if>
|
||||
</c:forEach>
|
||||
|
||||
@@ -202,28 +202,6 @@
|
||||
]
|
||||
};
|
||||
|
||||
var rpcdata = {
|
||||
"nodes":[
|
||||
<c:forEach items="${rpcnodes}" var="node" varStatus="status">
|
||||
<c:if test="${node.terminal}">
|
||||
{"name":"${node.serviceName}:${node.rpc}"}
|
||||
</c:if>
|
||||
<c:if test="${not node.terminal}">
|
||||
{"name":"${node}"}
|
||||
</c:if>
|
||||
<c:if test="${!status.last}">,
|
||||
</c:if>
|
||||
</c:forEach>
|
||||
],
|
||||
"links":[
|
||||
<c:forEach items="${rpclinks}" var="link" varStatus="status">
|
||||
{"source":${link.from.sequence}, "target":${link.to.sequence}, "value":${link.callCount}}
|
||||
<c:if test="${!status.last}">,
|
||||
</c:if>
|
||||
</c:forEach>
|
||||
]
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
drawSankeyChart(data, "#graph", 960, 500);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user