mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-28 06:08:43 +10:00
[유치수] [NOBTS] add calltree
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@708 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.nhn.hippo.web.calltree;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public class RPC implements Comparable<RPC> {
|
||||
private int sequence;
|
||||
private final String id;
|
||||
private final String agentId;
|
||||
private final String serviceName;
|
||||
private final String rpc;
|
||||
|
||||
public RPC(String agentId, String serviceName, String rpc) {
|
||||
this.id = agentId + ":" + serviceName + ":" + rpc;
|
||||
this.agentId = agentId;
|
||||
this.serviceName = serviceName;
|
||||
this.rpc = rpc;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setSequence(int sequence) {
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
public int getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public String getRpc() {
|
||||
return rpc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(RPC rpc) {
|
||||
return id.compareTo(rpc.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id + ", seq=" + sequence;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.nhn.hippo.web.calltree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.profiler.common.dto.thrift.Span;
|
||||
|
||||
/**
|
||||
* Call Tree
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public class RPCCallTree {
|
||||
|
||||
private final String PREFIX_CLIENT = "CLIENT:";
|
||||
|
||||
private final Map<String, RPC> rpcs = new HashMap<String, RPC>();
|
||||
private final Map<String, String> spanIdToRPCId = new HashMap<String, String>();
|
||||
private final Map<String, Request> requests = new HashMap<String, Request>();
|
||||
private final List<Span> spans = new ArrayList<Span>();
|
||||
|
||||
private boolean isBuilt = false;
|
||||
|
||||
public void addSpan(Span span) {
|
||||
System.out.println("Add span to calltree=" + span + "\n");
|
||||
|
||||
/**
|
||||
* make RPCs
|
||||
*/
|
||||
// TODO: 여기에서 이러지말고 수집할 때 처음부터 table에 저장해둘 수 있나??
|
||||
RPC rpc = new RPC(span.getAgentID(), span.getServiceName(), span.getName());
|
||||
if (!rpcs.containsKey(rpc.getId())) {
|
||||
rpcs.put(rpc.getId(), rpc);
|
||||
}
|
||||
spanIdToRPCId.put(String.valueOf(span.getSpanID()), rpc.getId());
|
||||
|
||||
if (span.getParentSpanId() == -1) {
|
||||
RPC client = new RPC(PREFIX_CLIENT + span.getAgentID(), span.getServiceName(), span.getName());
|
||||
rpcs.put(client.getId(), client);
|
||||
spanIdToRPCId.put(PREFIX_CLIENT + span.getSpanID(), client.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Preparing makes link (requests)
|
||||
*/
|
||||
spans.add(span);
|
||||
}
|
||||
|
||||
public RPCCallTree build() {
|
||||
if (isBuilt)
|
||||
return this;
|
||||
|
||||
int i = 0;
|
||||
for (Entry<String, RPC> entry : rpcs.entrySet()) {
|
||||
entry.getValue().setSequence(i++);
|
||||
}
|
||||
|
||||
for (Span span : spans) {
|
||||
String from = String.valueOf(span.getParentSpanId());
|
||||
String to = String.valueOf(span.getSpanID());
|
||||
|
||||
RPC fromRPC = rpcs.get(spanIdToRPCId.get(from));
|
||||
RPC toRPC = rpcs.get(spanIdToRPCId.get(to));
|
||||
|
||||
if (fromRPC == null) {
|
||||
fromRPC = rpcs.get(spanIdToRPCId.get(PREFIX_CLIENT + to));
|
||||
}
|
||||
|
||||
Request request = new Request(fromRPC, toRPC);
|
||||
if (requests.containsKey(request.getId())) {
|
||||
requests.get(request.getId()).increaseCallCount();
|
||||
} else {
|
||||
requests.put(request.getId(), request);
|
||||
}
|
||||
}
|
||||
|
||||
isBuilt = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Collection<RPC> getNodes() {
|
||||
return this.rpcs.values();
|
||||
}
|
||||
|
||||
public Collection<Request> getLinks() {
|
||||
return this.requests.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("RPCS=").append(rpcs);
|
||||
sb.append("\n");
|
||||
sb.append("REQUESTS=").append(requests.values());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.nhn.hippo.web.calltree;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public class Request {
|
||||
private final String id;
|
||||
private final RPC from;
|
||||
private final RPC to;
|
||||
private int callCount = 1;
|
||||
|
||||
public Request(RPC from, RPC to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.id = from.getId() + to.getId();
|
||||
}
|
||||
|
||||
public void increaseCallCount() {
|
||||
callCount++;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public RPC getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public RPC getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public int getCallCount() {
|
||||
return callCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{from=").append(from).append(", to=").append(to).append(", cc=").append(callCount).append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,15 @@ 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.calltree.RPCCallTree;
|
||||
import com.nhn.hippo.web.service.FlowChartService;
|
||||
|
||||
/**
|
||||
* retrieve data for drawing call tree.
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
public class FlowChartController {
|
||||
|
||||
@@ -20,8 +27,7 @@ public class FlowChartController {
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* testurl = http://localhost:7080/flow.hippo?host=TEST_AGENT_ID&from=1348453800000&to=1348453900000
|
||||
* testurl = http://localhost:7080/flow.hippo?host=TEST_AGENT_ID&from=0&to=1348493900000
|
||||
* testurl = netscurl "http://localhost:7080/flow.hippo?host=TEST_AGENT_ID&from=1348565386677&to=1348565386677"
|
||||
* </pre>
|
||||
*
|
||||
* @param model
|
||||
@@ -36,18 +42,22 @@ public class FlowChartController {
|
||||
* get agentId list from 'Servers'
|
||||
*/
|
||||
String[] selectAgentIds = flow.selectAgentIds(hosts);
|
||||
|
||||
System.out.println("selectedAgentIds=" + Arrays.toString(selectAgentIds));
|
||||
|
||||
/**
|
||||
* get traceId list from 'TraceIndex'
|
||||
*/
|
||||
List<byte[]> iterator = flow.selectTraceIdsFromTraceIndex(hosts, from, to);
|
||||
List<byte[]> traceIds = flow.selectTraceIdsFromTraceIndex(hosts, from, to);
|
||||
|
||||
/**
|
||||
* get all traces from 'Trace'
|
||||
* get call tree
|
||||
*/
|
||||
flow.selectTraces(iterator);
|
||||
RPCCallTree callTree = flow.selectCallTree(traceIds);
|
||||
model.addAttribute("nodes", callTree.getNodes());
|
||||
model.addAttribute("links", callTree.getLinks());
|
||||
model.addAttribute("value", "hello world");
|
||||
|
||||
System.out.println(callTree.toString());
|
||||
|
||||
return "flow";
|
||||
}
|
||||
|
||||
@@ -2,15 +2,48 @@ package com.nhn.hippo.web.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.nhn.hippo.web.calltree.RPCCallTree;
|
||||
import com.profiler.common.dto.thrift.Span;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public interface FlowChartService {
|
||||
|
||||
/**
|
||||
* select agentIds from Server table
|
||||
*
|
||||
* @param hosts
|
||||
* @return
|
||||
*/
|
||||
public String[] selectAgentIds(String[] hosts);
|
||||
|
||||
/**
|
||||
* select traceIds from TraceIndex table
|
||||
*
|
||||
* @param agentIds
|
||||
* @param from
|
||||
* @param to
|
||||
* @return
|
||||
*/
|
||||
public List<byte[]> selectTraceIdsFromTraceIndex(String[] agentIds, long from, long to);
|
||||
|
||||
/**
|
||||
* select Traces from Trace table
|
||||
*
|
||||
* @param traceIds
|
||||
* @return
|
||||
*/
|
||||
public Map<byte[], List<Span>> selectTraces(List<byte[]> traceIds);
|
||||
|
||||
/**
|
||||
* select call tree
|
||||
*
|
||||
* @param traceIds
|
||||
* @return
|
||||
*/
|
||||
public RPCCallTree selectCallTree(List<byte[]> traceIds);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.nhn.hippo.web.calltree.RPCCallTree;
|
||||
import com.profiler.common.dto.thrift.Span;
|
||||
import com.profiler.common.hbase.HBaseClient;
|
||||
import com.profiler.common.hbase.HBaseQuery;
|
||||
@@ -99,20 +100,17 @@ public class FlowChartServiceImpl implements FlowChartService {
|
||||
|
||||
TDeserializer deserializer = new TDeserializer();
|
||||
|
||||
/**
|
||||
* Map<FAMILY, Map<COLUMN_NAME, Map<Timestamp, VALUE>>>
|
||||
*/
|
||||
NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = res.getMap();
|
||||
|
||||
for (Entry<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> entry : map.entrySet()) {
|
||||
byte[] family = entry.getKey();
|
||||
System.out.println("family=" + Bytes.toString(family));
|
||||
// byte[] family = entry.getKey();
|
||||
// System.out.println("family=" + Bytes.toString(family));
|
||||
|
||||
NavigableMap<byte[], NavigableMap<Long, byte[]>> values = entry.getValue();
|
||||
|
||||
for (Entry<byte[], NavigableMap<Long, byte[]>> value : values.entrySet()) {
|
||||
byte[] colname = value.getKey();
|
||||
System.out.println("colname=" + Bytes.toString(colname));
|
||||
// byte[] colname = value.getKey();
|
||||
// System.out.println("colname=" + Bytes.toString(colname));
|
||||
|
||||
NavigableMap<Long, byte[]> valueSeries = value.getValue();
|
||||
|
||||
@@ -131,4 +129,15 @@ public class FlowChartServiceImpl implements FlowChartService {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCCallTree selectCallTree(List<byte[]> traceIds) {
|
||||
List<Get> gets = new ArrayList<Get>(traceIds.size());
|
||||
for (byte[] traceId : traceIds) {
|
||||
gets.add(new Get(traceId));
|
||||
}
|
||||
|
||||
Result[] results = client.get(HBaseTables.TRACES, gets);
|
||||
|
||||
return TracesProcessor.process(results);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.nhn.hippo.web.service;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
import org.apache.hadoop.hbase.client.Result;
|
||||
import org.apache.thrift.TDeserializer;
|
||||
import org.apache.thrift.TException;
|
||||
|
||||
import com.nhn.hippo.web.calltree.RPCCallTree;
|
||||
import com.profiler.common.dto.thrift.Span;
|
||||
|
||||
public class TracesProcessor {
|
||||
|
||||
public static RPCCallTree process(Result[] results) {
|
||||
RPCCallTree callTree = new RPCCallTree();
|
||||
|
||||
TDeserializer deserializer = new TDeserializer();
|
||||
|
||||
for (Result res : results) {
|
||||
/**
|
||||
* res.getMap() represent
|
||||
* "Map<FAMILY, Map<COLUMN_NAME, Map<Timestamp, VALUE>>>"
|
||||
*/
|
||||
NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = res.getMap();
|
||||
|
||||
for (Entry<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> entry : map.entrySet()) {
|
||||
NavigableMap<byte[], NavigableMap<Long, byte[]>> values = entry.getValue();
|
||||
|
||||
/**
|
||||
* For each column (SpanID)
|
||||
*/
|
||||
for (Entry<byte[], NavigableMap<Long, byte[]>> value : values.entrySet()) {
|
||||
NavigableMap<Long, byte[]> valueSeries = value.getValue();
|
||||
|
||||
/**
|
||||
* Decode span object
|
||||
*/
|
||||
for (Entry<Long, byte[]> v : valueSeries.entrySet()) {
|
||||
Span span = new Span();
|
||||
try {
|
||||
deserializer.deserialize(span, v.getValue());
|
||||
callTree.addSpan(span);
|
||||
} catch (TException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return callTree.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.nhn.hippo.web.timeline;
|
||||
|
||||
/**
|
||||
* Trace Timeline
|
||||
*
|
||||
* @author netspider
|
||||
*
|
||||
*/
|
||||
public class Timeline {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user