[강운덕] [LUCYSUS-1744] hbase 저장시의 데이터를 컴팩트하게 함.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@808 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2012-10-18 05:42:20 +00:00
parent 1e843127cf
commit 4641a6e159
21 changed files with 407 additions and 202 deletions
@@ -7,7 +7,9 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.bo.SpanBo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Call Tree
@@ -16,16 +18,18 @@ import com.profiler.common.dto.thrift.Span;
*/
public class RPCCallTree {
private Logger logger = LoggerFactory.getLogger(this.getClass());
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, RPCRequest> requests = new HashMap<String, RPCRequest>();
private final List<Span> spans = new ArrayList<Span>();
private final List<SpanBo> spans = new ArrayList<SpanBo>();
private boolean isBuilt = false;
public void addSpan(Span span) {
public void addSpan(SpanBo span) {
/**
* make RPCs
*/
@@ -64,7 +68,7 @@ public class RPCCallTree {
entry.getValue().setSequence(i++);
}
for (Span span : spans) {
for (SpanBo span : spans) {
String from = String.valueOf(span.getParentSpanId());
String to = String.valueOf(span.getSpanId());
@@ -74,7 +78,12 @@ public class RPCCallTree {
if (fromRPC == null) {
fromRPC = rpcs.get(spanIdToRPCId.get(PREFIX_CLIENT + to));
}
// TODO 없는 url에 대한 호출이 고려되어야 함. 일단 임시로 회피.
if (fromRPC == null) {
logger.debug("invalid fromrpc {}", from);
continue;
}
logger.debug("form:{}, to:{}", fromRPC, to);
RPCRequest request = new RPCRequest(fromRPC, toRPC);
if (requests.containsKey(request.getId())) {
requests.get(request.getId()).increaseCallCount();
@@ -10,6 +10,12 @@ public class RPCRequest {
private int callCount = 1;
public RPCRequest(RPC from, RPC to) {
if (from == null) {
throw new NullPointerException("form must not be null");
}
if (to == null) {
throw new NullPointerException("to must not be null");
}
this.from = from;
this.to = to;
this.id = from.getId() + to.getId();
@@ -8,7 +8,9 @@ import java.util.Map;
import java.util.Map.Entry;
import com.nhn.hippo.web.vo.BusinessTransactions;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.bo.SpanBo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Call Tree
@@ -17,17 +19,19 @@ import com.profiler.common.dto.thrift.Span;
*/
public class ServerCallTree {
private Logger logger = LoggerFactory.getLogger(this.getClass());
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 final List<SpanBo> spans = new ArrayList<SpanBo>();
private final BusinessTransactions businessTransactions = new BusinessTransactions();
private boolean isBuilt = false;
public void addSpan(Span span) {
public void addSpan(SpanBo span) {
/**
* make Servers
*/
@@ -70,7 +74,7 @@ public class ServerCallTree {
entry.getValue().setSequence(i++);
}
for (Span span : spans) {
for (SpanBo span : spans) {
String from = String.valueOf(span.getParentSpanId());
String to = String.valueOf(span.getSpanId());
@@ -81,6 +85,11 @@ public class ServerCallTree {
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: local call인 경우 보여주지 않음.
@@ -10,6 +10,12 @@ public class ServerRequest {
private int callCount = 1;
public ServerRequest(Server from, Server to) {
if (from == null) {
throw new NullPointerException("from must not be null");
}
if (to == null) {
throw new NullPointerException("to must not be null");
}
this.from = from;
this.to = to;
this.id = from.getId() + to.getId();
@@ -1,5 +1,6 @@
package com.nhn.hippo.web.calltree.span;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
import org.apache.commons.lang.StringUtils;
@@ -8,9 +9,9 @@ import org.apache.commons.lang.StringUtils;
*/
public class SpanAlign {
private int depth;
private Span span;
private SpanBo span;
public SpanAlign(int depth, Span span) {
public SpanAlign(int depth, SpanBo span) {
this.depth = depth;
this.span = span;
}
@@ -27,7 +28,7 @@ public class SpanAlign {
// return sb.toString();
// }
public Span getSpan() {
public SpanBo getSpan() {
return span;
}
}
@@ -1,5 +1,6 @@
package com.nhn.hippo.web.calltree.span;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,18 +14,18 @@ public class SpanAligner {
public static final Long SPAN_ROOT = -1L;
private Logger logger = LoggerFactory.getLogger(this.getClass());
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private List<Span> spans;
private List<SpanBo> spans;
// private Map<Long, Span> spanIdMap;
private Map<Long, List<Span>> parentSpanIdMap;
private Map<Long, List<SpanBo>> parentSpanIdMap;
private int depth = 0;
private static final Comparator<Span> timeComparator = new Comparator<Span>() {
private static final Comparator<SpanBo> timeComparator = new Comparator<SpanBo>() {
@Override
public int compare(Span o1, Span o2) {
public int compare(SpanBo o1, SpanBo o2) {
long o1Timestamp = o1.getTimestamp();
long o2Timestamp = o2.getTimestamp();
if (o1Timestamp > o2Timestamp) {
@@ -37,7 +38,7 @@ public class SpanAligner {
}
};
public SpanAligner(List<Span> spans) {
public SpanAligner(List<SpanBo> spans) {
this.spans = spans;
}
@@ -46,28 +47,28 @@ public class SpanAligner {
List<SpanAlign> result = new ArrayList<SpanAlign>(spans.size());
Span root = findRoot();
SpanBo root = findRoot();
logger.debug("find root {}", root);
result.add(new SpanAlign(0, root));
List<Span> next = nextSpan(root);
List<SpanBo> next = nextSpan(root);
doNext(next, result);
return result;
}
public void buildIndex() {
SpanIdChecker spanIdCheck = new SpanIdChecker(spans);
Map<Long, List<Span>> parentSpanIdMap = new HashMap<Long, List<Span>>();
Map<Long, List<SpanBo>> parentSpanIdMap = new HashMap<Long, List<SpanBo>>();
for (Span span : spans) {
for (SpanBo span : spans) {
spanIdCheck.check(span);
long parentSpanId = span.getParentSpanId();
List<Span> spanList = parentSpanIdMap.get(parentSpanId);
List<SpanBo> spanList = parentSpanIdMap.get(parentSpanId);
if (spanList != null) {
spanList.add(span);
} else {
LinkedList<Span> newSpanList = new LinkedList<Span>();
LinkedList<SpanBo> newSpanList = new LinkedList<SpanBo>();
newSpanList.add(span);
parentSpanIdMap.put(parentSpanId, newSpanList);
}
@@ -77,20 +78,20 @@ public class SpanAligner {
this.parentSpanIdMap = parentSpanIdMap;
}
private void doNext(List<Span> spans, List<SpanAlign> result) {
private void doNext(List<SpanBo> spans, List<SpanAlign> result) {
if (spans == null) {
return;
}
depth++;
try {
for (Span next : spans) {
for (SpanBo next : spans) {
if (logger.isDebugEnabled()) {
logger.debug("{} {} next {}", new Object[]{getSpace(), depth, next});
}
result.add(new SpanAlign(depth, next));
List<Span> nextSpan = nextSpan(next);
List<SpanBo> nextSpan = nextSpan(next);
doNext(nextSpan, result);
}
} finally {
@@ -108,8 +109,8 @@ public class SpanAligner {
}
private List<Span> nextSpan(Span parent) {
List<Span> child = this.parentSpanIdMap.get(parent.getSpanId());
private List<SpanBo> nextSpan(SpanBo parent) {
List<SpanBo> child = this.parentSpanIdMap.get(parent.getSpanId());
if (child == null) {
return null;
}
@@ -120,8 +121,8 @@ public class SpanAligner {
}
private Span findRoot() {
List<Span> root = this.parentSpanIdMap.get(SPAN_ROOT);
private SpanBo findRoot() {
List<SpanBo> root = this.parentSpanIdMap.get(SPAN_ROOT);
if (root == null) {
logger.warn("root span not found. {}", spans);
throw new IllegalStateException("root span not found");
@@ -134,15 +135,15 @@ public class SpanAligner {
}
public static class SpanIdChecker {
private Map<Long, Span> spanCheck = new HashMap<Long, Span>();
private List<Span> spans;
private Map<Long, SpanBo> spanCheck = new HashMap<Long, SpanBo>();
private List<SpanBo> spans;
public SpanIdChecker(List<Span> spans) {
public SpanIdChecker(List<SpanBo> spans) {
this.spans = spans;
}
public void check(Span span) {
Span before = spanCheck.put(span.getSpanId(), span);
public void check(SpanBo span) {
SpanBo before = spanCheck.put(span.getSpanId(), span);
if (before != null) {
// span id 중복체크
deplicatedSpanIdDump(span);
@@ -150,7 +151,7 @@ public class SpanAligner {
}
}
private void deplicatedSpanIdDump(Span span) {
private void deplicatedSpanIdDump(SpanBo span) {
// 중복 span dump
Logger internalLog = LoggerFactory.getLogger(this.getClass());
internalLog.info("duplicated spanId {}, list:{}", span, spans);
@@ -2,6 +2,8 @@ package com.nhn.hippo.web.controller;
import java.util.Set;
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;
@@ -22,6 +24,8 @@ import com.nhn.hippo.web.vo.TraceId;
@Controller
public class FlowChartController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private FlowChartService flow;
@@ -35,7 +39,7 @@ public class FlowChartController {
model.addAttribute("nodes", callTree.getNodes());
model.addAttribute("links", callTree.getLinks());
System.out.println(callTree.toString());
logger.debug("callTree:{}", callTree);
return "flow";
}
@@ -51,7 +55,7 @@ public class FlowChartController {
model.addAttribute("links", callTree.getLinks());
model.addAttribute("businessTransactions", callTree.getBusinessTransactions().iterator());
System.out.println(callTree.toString());
logger.debug("callTree:{}", callTree);
return "flowserver";
}
@@ -1,6 +1,7 @@
package com.nhn.hippo.web.dao;
import com.nhn.hippo.web.vo.TraceId;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.hbase.HBaseTables;
import com.profiler.common.hbase.HbaseOperations2;
@@ -25,7 +26,10 @@ import java.util.UUID;
@Repository
public class HbaseTraceDao implements TraceDao {
private final byte[] COLFAM_SPAN = Bytes.toBytes("Span");
private final byte[] COLFAM_SPAN = HBaseTables.TRACES_CF_SPAN;
private final byte[] COLFAM_ANNOTATION = HBaseTables.TRACES_CF_ANNOTATION;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
@@ -33,23 +37,34 @@ public class HbaseTraceDao implements TraceDao {
@Autowired
@Qualifier("spanMapper")
private RowMapper<List<Span>> spanMapper;
private RowMapper<List<SpanBo>> spanMapper;
@Autowired
@Qualifier("spanAnnotationMapper")
private RowMapper<List<SpanBo>> spanAnnotationMapper;
@Override
public List<Span> selectSpan(UUID traceId) {
public List<SpanBo> selectSpan(UUID traceId) {
byte[] uuidBytes = BytesUtils.longLongToBytes(traceId.getMostSignificantBits(), traceId.getLeastSignificantBits());
return template2.get(HBaseTables.TRACES, uuidBytes, COLFAM_SPAN, spanMapper);
}
public List<SpanBo> selectSpanAndAnnotation(UUID traceId) {
byte[] uuidBytes = BytesUtils.longLongToBytes(traceId.getMostSignificantBits(), traceId.getLeastSignificantBits());
Get get = new Get(uuidBytes);
get.addFamily(COLFAM_SPAN);
get.addFamily(COLFAM_ANNOTATION);
return template2.get(HBaseTables.TRACES, get, spanAnnotationMapper);
}
@Override
public List<Span> selectSpan(long traceIdMost, long traceIdLeast) {
public List<SpanBo> selectSpan(long traceIdMost, long traceIdLeast) {
byte[] uuidBytes = BytesUtils.longLongToBytes(traceIdMost, traceIdLeast);
return template2.get(HBaseTables.TRACES, uuidBytes, COLFAM_SPAN, spanMapper);
}
@Override
public List<List<Span>> selectSpans(List<UUID> traceIds) {
public List<List<SpanBo>> selectSpans(List<UUID> traceIds) {
List<Get> gets = new ArrayList<Get>(traceIds.size());
for (UUID traceId : traceIds) {
byte[] uuidBytes = BytesUtils.longLongToBytes(traceId.getMostSignificantBits(), traceId.getLeastSignificantBits());
@@ -61,7 +76,7 @@ public class HbaseTraceDao implements TraceDao {
}
@Override
public List<List<Span>> selectSpans(Set<TraceId> traceIds) {
public List<List<SpanBo>> selectSpans(Set<TraceId> traceIds) {
List<Get> gets = new ArrayList<Get>(traceIds.size());
for (TraceId traceId : traceIds) {
Get get = new Get(traceId.getBytes());
@@ -70,4 +85,15 @@ public class HbaseTraceDao implements TraceDao {
}
return template2.get(HBaseTables.TRACES, gets, spanMapper);
}
public List<List<SpanBo>> selectSpansAndAnnotation(Set<TraceId> traceIds) {
List<Get> gets = new ArrayList<Get>(traceIds.size());
for (TraceId traceId : traceIds) {
Get get = new Get(traceId.getBytes());
get.addFamily(COLFAM_SPAN);
get.addFamily(COLFAM_ANNOTATION);
gets.add(get);
}
return template2.get(HBaseTables.TRACES, gets, spanAnnotationMapper);
}
}
@@ -2,6 +2,7 @@ package com.nhn.hippo.web.dao;
import com.nhn.hippo.web.vo.TraceId;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
import java.util.List;
@@ -13,12 +14,15 @@ import java.util.UUID;
*/
public interface TraceDao {
List<Span> selectSpan(UUID traceId);
List<SpanBo> selectSpan(UUID traceId);
List<Span> selectSpan(long traceIdMost, long traceIdLeast);
List<SpanBo> selectSpanAndAnnotation(UUID traceId);
List<List<Span>> selectSpans(List<UUID> traceIds);
List<SpanBo> selectSpan(long traceIdMost, long traceIdLeast);
List<List<Span>> selectSpans(Set<TraceId> traceIds);
List<List<SpanBo>> selectSpans(List<UUID> traceIds);
List<List<SpanBo>> selectSpans(Set<TraceId> traceIds);
List<List<SpanBo>> selectSpansAndAnnotation(Set<TraceId> traceIds);
}
@@ -0,0 +1,61 @@
package com.nhn.hippo.web.mapper;
import com.profiler.common.bo.AnnotationBo;
import com.profiler.common.hbase.HBaseTables;
import com.profiler.common.util.BytesUtils;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.hadoop.hbase.RowMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*/
public class AnnotationMapper implements RowMapper<Map<Long, List<AnnotationBo>>> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Map<Long, List<AnnotationBo>> mapRow(Result result, int rowNum) throws Exception {
KeyValue[] keyList = result.raw();
Map<Long, List<AnnotationBo>> annotationList = new HashMap<Long, List<AnnotationBo>>();
for (KeyValue kv : keyList) {
byte[] buffer = kv.getBuffer();
long spanId = BytesUtils.bytesToLong(buffer, kv.getQualifierOffset());
int offset = kv.getValueOffset();
if (kv.getFamilyLength() == HBaseTables.TRACES_CF_ANNOTATION.length) {
// byte[] value = kv.getValue();
// if(value == null) {
// continue;
// }
int valueLength = kv.getValueLength();
if (valueLength == 0) {
continue;
}
int size = BytesUtils.bytesToInt(buffer, offset);
if (size == 0) {
continue;
}
offset += 4;
List<AnnotationBo> bos = new ArrayList<AnnotationBo>(size);
for (int i = 0; i < size; i++) {
AnnotationBo annotationBo = new AnnotationBo();
annotationBo.setSpanId(spanId);
offset = annotationBo.readValue(buffer, offset);
bos.add(annotationBo);
logger.trace("read annotation:{}", annotationBo);
}
annotationList.put(spanId, bos);
}
}
return annotationList;
}
}
@@ -33,8 +33,8 @@ public class JavaObjectDecoder implements BinaryAnnotationDecoder {
// ByteArrayInputStream ins = new ByteArrayInputStream(binaryAnnotation.getValue());
// try {
// ObjectInputStream in = new ObjectInputStream(ins);
// Object readObject = in.readObject();
// return readObject;
// Object readValue = in.readValue();
// return readValue;
// } catch (IOException e) {
// logger.warn("binaryAnnotation decode fail Cause:{}", e.getMessage(), e);
// return "binaryAnnotation decode fail Cause:" + e.getMessage();
@@ -1,53 +1,112 @@
package com.nhn.hippo.web.mapper;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.bo.AnnotationBo;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.hbase.HBaseTables;
import com.profiler.common.util.BytesUtils;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.thrift.TDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NavigableMap;
import java.util.Map;
/**
*
*/
@Component
public class SpanMapper implements RowMapper<List<Span>> {
public class SpanMapper implements RowMapper<List<SpanBo>> {
private final byte[] COLFAM_SPAN = Bytes.toBytes("Span");
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// private BinaryAnnotationDecoder binaryAnnotationDecoder = new JavaObjectDecoder();
private AnnotationMapper annotationMapper;
public AnnotationMapper getAnnotationMapper() {
return annotationMapper;
}
public void setAnnotationMapper(AnnotationMapper annotationMapper) {
this.annotationMapper = annotationMapper;
}
@Override
public List<Span> mapRow(Result result, int rowNum) throws Exception {
NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(COLFAM_SPAN);
if (familyMap == null) {
return Collections.emptyList();
public List<SpanBo> mapRow(Result result, int rowNum) throws Exception {
byte[] rowKey = result.getRow();
long most = BytesUtils.bytesToFirstLong(rowKey);
long least = BytesUtils.bytesToSecondLong(rowKey);
KeyValue[] keyList = result.raw();
List<SpanBo> spanList = new ArrayList<SpanBo>();
for (KeyValue kv : keyList) {
// family name "span"일때로만 한정.
if (kv.getFamilyLength() == HBaseTables.TRACES_CF_SPAN.length) {
SpanBo spanBo = new SpanBo();
spanBo.setMostTraceId(most);
spanBo.setLeastTraceId(least);
spanBo.setSpanID(Bytes.toLong(kv.getBuffer(), kv.getQualifierOffset()));
spanBo.setSpanID(Bytes.toLong(kv.getQualifier()));
spanBo.setTimestamp(kv.getTimestamp());
spanBo.readValue(kv.getBuffer(), kv.getValueOffset());
if (logger.isTraceEnabled()) {
logger.trace("read span :{}", spanBo);
}
spanList.add(spanBo);
}
}
if (annotationMapper != null) {
Map<Long, List<AnnotationBo>> annotationMap = annotationMapper.mapRow(result, rowNum);
addAnnotation(spanList, annotationMap);
}
List<Span> spanList = new ArrayList<Span>(familyMap.size());
// TODO thrift 포멧이 아니고 따로 풀어서 넣어야 될거 같음.
TDeserializer de = new TDeserializer();
for (NavigableMap.Entry<byte[], byte[]> entry : familyMap.entrySet()) {
Span span = new Span();
// spainid가 이미 value에 들어 있어서 일단 필요가 없음.
//byte[] spanId = entry.getKey();
de.deserialize(span, entry.getValue());
// if (binaryAnnotationDecoder != null) {
// binaryAnnotationDecoder.decode(span);
// }
if (logger.isDebugEnabled()) {
logger.debug("deserailze span :{}", span);
}
spanList.add(span);
}
return spanList;
// NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(COLFAM_SPAN);
// if (familyMap == null) {
// return Collections.emptyList();
// }
// List<SpanBo> spanList = new ArrayList<SpanBo>(familyMap.size());
// Put put = new Put(SpanUtils.getTracesRowkey(span), span.getTimestamp());
// // TODO columName이 중복일 경우를 확인가능하면 span id 중복 발급을 알수 있음.
// put.add(COLFAM_SPAN, Bytes.toBytes(span.getSpanID()), value);
// byte[] rowKey = result.getRow();
// long most = BytesUtils.bytesToFirstLong(rowKey);
// long least = BytesUtils.bytesToSecondLong(rowKey);
//
// for (NavigableMap.Entry<byte[], byte[]> entry : familyMap.entrySet()) {
// SpanBo spanBo = new SpanBo();
//
// spanBo.setMostTraceID(most);
// spanBo.setLeastTraceID(least);
// spanBo.setSpanID(Bytes.toLong(entry.getKey()));
// //
// //byte[] spanId = entry.getKey();
//// if (binaryAnnotationDecoder != null) {
//// binaryAnnotationDecoder.decode(span);
//// }
//
// if (logger.isDebugEnabled()) {
// logger.debug("read span :{}", spanBo);
// }
// spanList.add(spanBo);
// }
// return spanList;
}
private void addAnnotation(List<SpanBo> spanList, Map<Long, List<AnnotationBo>> annotationMap) {
for (SpanBo bo : spanList) {
long spanID = bo.getSpanId();
List<AnnotationBo> anoList = annotationMap.get(spanID);
bo.setAnnotationBoList(anoList);
}
}
}
@@ -6,6 +6,7 @@ import com.nhn.hippo.web.dao.TraceDao;
import com.nhn.hippo.web.dao.TraceIndexDao;
import com.nhn.hippo.web.service.TracesProcessor.SpanHandler;
import com.nhn.hippo.web.vo.TraceId;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.hbase.HBaseClient;
import com.profiler.common.hbase.HBaseQuery;
@@ -67,6 +68,9 @@ public class FlowChartServiceImpl implements FlowChartService {
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);
// 이런 필터로직을 scan filter에서 할수 없나?
Set<TraceId> result = new HashSet<TraceId>();
@@ -120,9 +124,9 @@ public class FlowChartServiceImpl implements FlowChartService {
@Override
public RPCCallTree selectRPCCallTree(Set<TraceId> traceIds) {
final RPCCallTree tree = new RPCCallTree();
List<List<Span>> traces = this.traceDao.selectSpans(traceIds);
for (List<Span> transaction : traces) {
for (Span eachTransaction : transaction) {
List<List<SpanBo>> traces = this.traceDao.selectSpans(traceIds);
for (List<SpanBo> transaction : traces) {
for (SpanBo eachTransaction : transaction) {
tree.addSpan(eachTransaction);
}
}
@@ -133,10 +137,10 @@ public class FlowChartServiceImpl implements FlowChartService {
public ServerCallTree selectServerCallTree(Set<TraceId> traceIds) {
final ServerCallTree tree = new ServerCallTree();
List<List<Span>> traces = this.traceDao.selectSpans(traceIds);
List<List<SpanBo>> traces = this.traceDao.selectSpansAndAnnotation(traceIds);
for (List<Span> transaction : traces) {
for (Span eachTransaction : transaction) {
for (List<SpanBo> transaction : traces) {
for (SpanBo eachTransaction : transaction) {
tree.addSpan(eachTransaction);
}
}
@@ -3,7 +3,7 @@ package com.nhn.hippo.web.service;
import com.nhn.hippo.web.calltree.span.SpanAlign;
import com.nhn.hippo.web.calltree.span.SpanAligner;
import com.nhn.hippo.web.dao.TraceDao;
import com.profiler.common.dto.thrift.Span;
import com.profiler.common.bo.SpanBo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,8 +27,7 @@ public class SpanServiceImpl implements SpanService {
@Override
public List<SpanAlign> selectSpan(String uuid) {
UUID id = UUID.fromString(uuid);
List<Span> spans = traceDao.selectSpan(id);
logger.debug("spans11 {}", spans);
List<SpanBo> spans = traceDao.selectSpanAndAnnotation(id);
if (spans == null) {
return Collections.emptyList();
}
@@ -42,7 +41,7 @@ public class SpanServiceImpl implements SpanService {
}
private List<SpanAlign> order(List<Span> spans) {
private List<SpanAlign> order(List<SpanBo> spans) {
SpanAligner spanAligner = new SpanAligner(spans);
return spanAligner.sort();
@@ -4,84 +4,86 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.profiler.common.bo.AnnotationBo;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Annotation;
import com.profiler.common.dto.thrift.Span;
public class BusinessTransaction {
private final List<String> traces = new ArrayList<String>();
private final String name;
private final List<String> traces = new ArrayList<String>();
private final String name;
private int calls = 0;
private long totalTime = 0;
private long maxTime = 0;
private long minTime = 0;
private int calls = 0;
private long totalTime = 0;
private long maxTime = 0;
private long minTime = 0;
public BusinessTransaction(Span span) {
this.name = span.getName();
this.traces.add(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString());
calls++;
public BusinessTransaction(SpanBo span) {
this.name = span.getName();
this.traces.add(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString());
calls++;
List<Annotation> annotations = span.getAnnotations();
long begin = 0;
long end = 0;
for (Annotation a : annotations) {
if (a.getKey().equals("SR") || a.getKey().equals("CS")) {
begin = a.getTimestamp();
}
if (a.getKey().equals("SS") || a.getKey().equals("CR")) {
end = a.getTimestamp();
}
}
long elapsed = end - begin;
totalTime = maxTime = minTime = elapsed;
}
List<AnnotationBo> annotations = span.getAnnotationBoList();
long begin = 0;
long end = 0;
for (AnnotationBo a : annotations) {
if (a.getKey().equals("SR") || a.getKey().equals("CS")) {
begin = a.getTimestamp();
}
if (a.getKey().equals("SS") || a.getKey().equals("CR")) {
end = a.getTimestamp();
}
}
long elapsed = end - begin;
totalTime = maxTime = minTime = elapsed;
}
public void add(Span span) {
this.traces.add(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString());
if (span.getParentSpanId() == -1) {
calls++;
}
public void add(SpanBo span) {
this.traces.add(new UUID(span.getMostTraceId(), span.getLeastTraceId()).toString());
if (span.getParentSpanId() == -1) {
calls++;
}
List<Annotation> annotations = span.getAnnotations();
long begin = 0;
long end = 0;
for (Annotation a : annotations) {
if (a.getKey().equals("SR") || a.getKey().equals("CS")) {
begin = a.getTimestamp();
}
if (a.getKey().equals("SS") || a.getKey().equals("CR")) {
end = a.getTimestamp();
}
}
long elapsed = end - begin;
totalTime += elapsed;
if (maxTime < elapsed)
maxTime = elapsed;
if (minTime > elapsed)
minTime = elapsed;
}
List<AnnotationBo> annotations = span.getAnnotationBoList();
long begin = 0;
long end = 0;
for (AnnotationBo a : annotations) {
if (a.getKey().equals("SR") || a.getKey().equals("CS")) {
begin = a.getTimestamp();
}
if (a.getKey().equals("SS") || a.getKey().equals("CR")) {
end = a.getTimestamp();
}
}
long elapsed = end - begin;
totalTime += elapsed;
if (maxTime < elapsed)
maxTime = elapsed;
if (minTime > elapsed)
minTime = elapsed;
}
public String getName() {
return name;
}
public String getName() {
return name;
}
public List<String> getTraces() {
return traces;
}
public List<String> getTraces() {
return traces;
}
public int getCalls() {
return calls;
}
public int getCalls() {
return calls;
}
public long getTotalTime() {
return totalTime;
}
public long getTotalTime() {
return totalTime;
}
public long getMaxTime() {
return maxTime;
}
public long getMaxTime() {
return maxTime;
}
public long getMinTime() {
return minTime;
}
public long getMinTime() {
return minTime;
}
}
@@ -5,41 +5,42 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.dto.thrift.Span;
public final class BusinessTransactions implements Iterable<BusinessTransaction> {
private final Map<String, BusinessTransaction> transactions = new HashMap<String, BusinessTransaction>();
private Iterator<Entry<String, BusinessTransaction>> iterator;
private final Map<String, BusinessTransaction> transactions = new HashMap<String, BusinessTransaction>();
private Iterator<Entry<String, BusinessTransaction>> iterator;
public void add(Span span) {
String name = span.getName();
if (transactions.containsKey(name)) {
transactions.get(name).add(span);
} else {
transactions.put(name, new BusinessTransaction(span));
}
}
public void add(SpanBo span) {
String name = span.getName();
if (transactions.containsKey(name)) {
transactions.get(name).add(span);
} else {
transactions.put(name, new BusinessTransaction(span));
}
}
@Override
public Iterator<BusinessTransaction> iterator() {
iterator = transactions.entrySet().iterator();
@Override
public Iterator<BusinessTransaction> iterator() {
iterator = transactions.entrySet().iterator();
return new Iterator<BusinessTransaction>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
return new Iterator<BusinessTransaction>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public BusinessTransaction next() {
return iterator.next().getValue();
}
@Override
public BusinessTransaction next() {
return iterator.next().getValue();
}
@Override
public void remove() {
@Override
public void remove() {
}
};
}
}
};
}
}