[유치수] [NOBTS] add server calltree

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@720 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Chisu Yu
2012-09-28 04:54:42 +00:00
parent 7ef13278ab
commit 52c97fa186
11 changed files with 308 additions and 96 deletions
@@ -21,7 +21,7 @@ public class RPCCallTree {
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 Map<String, RPCRequest> requests = new HashMap<String, RPCRequest>();
private final List<Span> spans = new ArrayList<Span>();
private boolean isBuilt = false;
@@ -77,7 +77,7 @@ public class RPCCallTree {
fromRPC = rpcs.get(spanIdToRPCId.get(PREFIX_CLIENT + to));
}
Request request = new Request(fromRPC, toRPC);
RPCRequest request = new RPCRequest(fromRPC, toRPC);
if (requests.containsKey(request.getId())) {
requests.get(request.getId()).increaseCallCount();
} else {
@@ -93,7 +93,7 @@ public class RPCCallTree {
return this.rpcs.values();
}
public Collection<Request> getLinks() {
public Collection<RPCRequest> getLinks() {
return this.requests.values();
}
@@ -5,13 +5,13 @@ package com.nhn.hippo.web.calltree;
* @author netspider
*
*/
public class Request {
public class RPCRequest {
private final String id;
private final RPC from;
private final RPC to;
private int callCount = 1;
public Request(RPC from, RPC to) {
public RPCRequest(RPC from, RPC to) {
this.from = from;
this.to = to;
this.id = from.getId() + to.getId();
@@ -0,0 +1,44 @@
package com.nhn.hippo.web.calltree;
/**
*
*
* @author netspider
*
*/
public class Server implements Comparable<Server> {
private int sequence;
private final String id;
private final String agentId;
public Server(String agentId, String endPoint) {
this.id = agentId + ":" + endPoint;
this.agentId = agentId;
}
public String getId() {
return this.id;
}
public void setSequence(int sequence) {
this.sequence = sequence;
}
public int getSequence() {
return sequence;
}
public String getAgentId() {
return agentId;
}
@Override
public int compareTo(Server server) {
return id.compareTo(server.id);
}
@Override
public String toString() {
return id;
}
}
@@ -0,0 +1,110 @@
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 ServerCallTree {
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<Span> spans = new ArrayList<Span>();
private boolean isBuilt = false;
public void addSpan(Span span) {
System.out.println("Add span to calltree=" + span + "\n");
/**
* make Servers
*/
// TODO: 여기에서 이러지말고 수집할 때 처음부터 table에 저장해둘 수 있나??
Server Server = new Server(span.getAgentID(), span.getEndPoint());
// 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);
}
spanIdToServerId.put(String.valueOf(span.getSpanID()), Server.getId());
if (span.getParentSpanId() == -1) {
Server client = new Server(PREFIX_CLIENT + span.getAgentID(), span.getEndPoint());
servers.put(client.getId(), client);
spanIdToServerId.put(PREFIX_CLIENT + span.getSpanID(), client.getId());
}
/**
* Preparing makes link (ServerRequests)
*/
spans.add(span);
}
public ServerCallTree build() {
if (isBuilt)
return this;
int i = 0;
for (Entry<String, Server> entry : servers.entrySet()) {
entry.getValue().setSequence(i++);
}
for (Span 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));
if (fromServer == null) {
fromServer = servers.get(spanIdToServerId.get(PREFIX_CLIENT + to));
}
ServerRequest ServerRequest = new ServerRequest(fromServer, toServer);
if (ServerRequests.containsKey(ServerRequest.getId())) {
ServerRequests.get(ServerRequest.getId()).increaseCallCount();
} else {
ServerRequests.put(ServerRequest.getId(), ServerRequest);
}
}
isBuilt = true;
return this;
}
public Collection<Server> getNodes() {
return this.servers.values();
}
public Collection<ServerRequest> getLinks() {
return this.ServerRequests.values();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Server=").append(servers);
sb.append("\n");
sb.append("ServerRequest=").append(ServerRequests.values());
return sb.toString();
}
}
@@ -0,0 +1,46 @@
package com.nhn.hippo.web.calltree;
/**
*
* @author netspider
*
*/
public class ServerRequest {
private final String id;
private final Server from;
private final Server to;
private int callCount = 1;
public ServerRequest(Server from, Server to) {
this.from = from;
this.to = to;
this.id = from.getId() + to.getId();
}
public void increaseCallCount() {
callCount++;
}
public String getId() {
return id;
}
public Server getFrom() {
return from;
}
public Server 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();
}
}
@@ -1,6 +1,5 @@
package com.nhn.hippo.web.controller;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,21 +37,10 @@ public class FlowChartController {
*/
@RequestMapping(value = "/flow", method = RequestMethod.GET)
public String arcus(Model model, @RequestParam("host") String[] hosts, @RequestParam("from") long from, @RequestParam("to") long to) {
/**
* get agentId list from 'Servers'
*/
String[] selectAgentIds = flow.selectAgentIds(hosts);
System.out.println("selectedAgentIds=" + Arrays.toString(selectAgentIds));
String[] agentIds = flow.selectAgentIds(hosts);
List<byte[]> traceIds = flow.selectTraceIdsFromTraceIndex(agentIds, from, to);
RPCCallTree callTree = flow.selectRPCCallTree(traceIds);
/**
* get traceId list from 'TraceIndex'
*/
List<byte[]> traceIds = flow.selectTraceIdsFromTraceIndex(hosts, from, to);
/**
* get call tree
*/
RPCCallTree callTree = flow.selectCallTree(traceIds);
model.addAttribute("nodes", callTree.getNodes());
model.addAttribute("links", callTree.getLinks());
model.addAttribute("value", "hello world");
@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import com.nhn.hippo.web.calltree.RPCCallTree;
import com.nhn.hippo.web.calltree.ServerCallTree;
import com.profiler.common.dto.thrift.Span;
/**
@@ -45,5 +46,13 @@ public interface FlowChartService {
* @param traceIds
* @return
*/
public RPCCallTree selectCallTree(List<byte[]> traceIds);
public RPCCallTree selectRPCCallTree(List<byte[]> traceIds);
/**
* select call tree
*
* @param traceIds
* @return
*/
public ServerCallTree selectServerCallTree(List<byte[]> traceIds);
}
@@ -5,20 +5,18 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import org.apache.commons.lang.ArrayUtils;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.thrift.TDeserializer;
import org.apache.thrift.TException;
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.nhn.hippo.web.calltree.ServerCallTree;
import com.nhn.hippo.web.service.TracesProcessor.SpanHandler;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.hbase.HBaseClient;
import com.profiler.common.hbase.HBaseQuery;
@@ -49,7 +47,11 @@ public class FlowChartServiceImpl implements FlowChartService {
System.out.println("selectedAgentId=" + iterator.next());
}
return null;
System.out.println("!!!==============WARNING==============!!!");
System.out.println("!!! selectAgentIds IS NOT IMPLEMENTED !!!");
System.out.println("!!!===================================!!!");
return hosts;
}
@Override
@@ -84,53 +86,26 @@ public class FlowChartServiceImpl implements FlowChartService {
Result[] results = client.get(HBaseTables.TRACES, gets);
// traceId, SpanList
Map<byte[], List<Span>> result = new HashMap<byte[], List<Span>>();
final Map<byte[], List<Span>> result = new HashMap<byte[], List<Span>>();
for (Result r : results) {
result.put(r.getRow(), populateSpans(r));
}
System.out.println("result=" + result);
TracesProcessor.process(results, new SpanHandler() {
@Override
public void handleSpan(byte[] row, byte[] family, byte[] column, Span span) {
if (result.containsKey(row)) {
result.get(row).add(span);
} else {
List<Span> list = new ArrayList<Span>();
list.add(span);
result.put(row, list);
}
}
});
return result;
}
private List<Span> populateSpans(Result res) {
List<Span> list = new ArrayList<Span>();
TDeserializer deserializer = new TDeserializer();
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));
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));
NavigableMap<Long, byte[]> valueSeries = value.getValue();
for (Entry<Long, byte[]> v : valueSeries.entrySet()) {
Span span = new Span();
try {
deserializer.deserialize(span, v.getValue());
list.add(span);
} catch (TException e) {
e.printStackTrace();
}
}
}
}
return list;
}
@Override
public RPCCallTree selectCallTree(List<byte[]> traceIds) {
public RPCCallTree selectRPCCallTree(List<byte[]> traceIds) {
List<Get> gets = new ArrayList<Get>(traceIds.size());
for (byte[] traceId : traceIds) {
gets.add(new Get(traceId));
@@ -138,6 +113,36 @@ public class FlowChartServiceImpl implements FlowChartService {
Result[] results = client.get(HBaseTables.TRACES, gets);
return TracesProcessor.process(results);
final RPCCallTree tree = new RPCCallTree();
TracesProcessor.process(results, new SpanHandler() {
@Override
public void handleSpan(byte[] row, byte[] family, byte[] column, Span span) {
tree.addSpan(span);
}
});
return tree.build();
}
@Override
public ServerCallTree selectServerCallTree(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);
final ServerCallTree tree = new ServerCallTree();
TracesProcessor.process(results, new SpanHandler() {
@Override
public void handleSpan(byte[] row, byte[] family, byte[] column, Span span) {
tree.addSpan(span);
}
});
return tree.build();
}
}
@@ -4,17 +4,24 @@ import java.util.Map.Entry;
import java.util.NavigableMap;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.thrift.TDeserializer;
import org.apache.thrift.TException;
import com.nhn.hippo.web.calltree.RPCCallTree;
import com.profiler.common.dto.thrift.Span;
/**
*
* @author netspider
*
*/
public class TracesProcessor {
public static RPCCallTree process(Result[] results) {
RPCCallTree callTree = new RPCCallTree();
public static interface SpanHandler {
void handleSpan(byte[] row, byte[] family, byte[] column, Span span);
}
public static void process(Result[] results, SpanHandler handler) {
TDeserializer deserializer = new TDeserializer();
for (Result res : results) {
@@ -25,12 +32,18 @@ public class TracesProcessor {
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));
NavigableMap<byte[], NavigableMap<Long, byte[]>> values = entry.getValue();
/**
* For each column (SpanID)
*/
for (Entry<byte[], NavigableMap<Long, byte[]>> value : values.entrySet()) {
byte[] colname = value.getKey();
System.out.println("colname=" + Bytes.toString(colname));
NavigableMap<Long, byte[]> valueSeries = value.getValue();
/**
@@ -40,7 +53,7 @@ public class TracesProcessor {
Span span = new Span();
try {
deserializer.deserialize(span, v.getValue());
callTree.addSpan(span);
handler.handleSpan(res.getRow(), family, colname, span);
} catch (TException e) {
e.printStackTrace();
}
@@ -48,7 +61,5 @@ public class TracesProcessor {
}
}
}
return callTree.build();
}
}