[유치수] [NOBTS] represent depth of each methods

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@1114 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Chisu Yu
2013-01-24 09:55:10 +00:00
parent d939e791f9
commit e39aed5488
6 changed files with 266 additions and 184 deletions
@@ -7,47 +7,61 @@ import com.profiler.common.bo.SubSpanBo;
*
*/
public class SpanAlign {
private int depth;
private SpanBo span;
private SubSpanBo subSpanBo;
private boolean root = true;
private int depth;
private SpanBo spanBo;
private SubSpanBo subSpanBo;
private boolean span = true;
public SpanAlign(int depth, SpanBo span) {
this.depth = depth;
this.span = span;
}
public SpanAlign(int depth, SpanBo spanBo) {
this.depth = depth;
this.spanBo = spanBo;
this.span = true;
}
public SpanAlign(int depth, SpanBo root, SubSpanBo subSpanBo) {
this.depth = depth;
this.span = root;
this.subSpanBo = subSpanBo;
}
public SpanAlign(int depth, SpanBo spanBo, SubSpanBo subSpanBo) {
this.depth = depth;
this.spanBo = spanBo;
this.subSpanBo = subSpanBo;
this.span = false;
}
public void setRoot(boolean root) {
this.root = root;
}
public void setSpan(boolean span) {
this.span = span;
}
public boolean isRoot() {
return root;
}
public boolean isSpan() {
return span;
}
public int getDepth() {
return depth;
}
public int getDepth() {
return depth;
}
// public String getDepthSpace() {
// StringBuilder sb = new StringBuilder(depth);
// for (int i = 0; i < depth; i++) {
// sb.append(' ');
// }
// return sb.toString();
// }
public SpanBo getSpan() {
return spanBo;
}
public SpanBo getSpan() {
return span;
}
public SubSpanBo getSubSpanBo() {
return subSpanBo;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("SpanAlign={");
sb.append("depth=").append(depth);
if (subSpanBo != null) {
sb.append(", orgDepth").append(subSpanBo.getDepth());
sb.append(", subSpabBo=").append(subSpanBo.getServiceName());
} else {
sb.append(", spabBo=").append(spanBo.getServiceName());
}
sb.append("}\n");
return sb.toString();
}
public SubSpanBo getSubSpanBo() {
return subSpanBo;
}
}
@@ -16,6 +16,7 @@ import com.profiler.common.bo.SpanBo;
/**
*
*/
@Deprecated
public class SpanAligner {
public static final Long SPAN_ROOT = -1L;
@@ -0,0 +1,72 @@
package com.nhn.hippo.web.calltree.span;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.profiler.common.bo.SpanBo;
import com.profiler.common.bo.SubSpanBo;
/**
*
* @author netspider
*
*/
public class SpanAligner2 {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Map<Long, SpanBo> spanMap;
public SpanAligner2(List<SpanBo> spans) {
spanMap = new HashMap<Long, SpanBo>(spans.size());
for (SpanBo span : spans) {
if (spanMap.containsKey(span.getSpanId())) {
throw new IllegalStateException("duplicated spanId. id:" + span.getSpanId());
}
this.spanMap.put((span.getParentSpanId() == -1) ? -1L : span.getSpanId(), span);
}
}
public List<SpanAlign> sort() {
List<SpanAlign> list = new ArrayList<SpanAlign>();
SpanBo root = spanMap.get(new Long(-1));
if (root == null) {
throw new IllegalStateException("root span not found");
}
populate(root, 0, list);
System.out.println(list);
return list;
}
private void populate(SpanBo parentSpan, int spanDepth, List<SpanAlign> container) {
int depth = spanDepth + 1;
SpanAlign element = new SpanAlign(depth, parentSpan);
container.add(element);
List<SubSpanBo> subSpanList = parentSpan.getSubSpanList();
for (SubSpanBo subSpanBo : subSpanList) {
if (subSpanBo.getDepth() != -1) {
depth = spanDepth + subSpanBo.getDepth() + 1;
}
SpanAlign sa = new SpanAlign(depth, parentSpan, subSpanBo);
container.add(sa);
Long nextSpanId = new Long(subSpanBo.getNextSpanId());
if (nextSpanId != -1 && spanMap.containsKey(nextSpanId)) {
populate(spanMap.get(new Long(nextSpanId)), depth, container);
}
}
}
}
@@ -11,6 +11,7 @@ import java.util.List;
/**
*
*/
@Deprecated
public class SpanPopulator {
private List<SpanAlign> list;
private int index = 0;
@@ -43,7 +44,7 @@ public class SpanPopulator {
long nextSpanStartTime = getNextSpanStartTime();
if (subStartTime <= nextSpanStartTime) {
SpanAlign subSpanAlign = new SpanAlign(spanAlign.getDepth(), span, subSpanBo);
subSpanAlign.setRoot(false);
subSpanAlign.setSpan(false);
populatedList.add(subSpanAlign);
} else {
if (nextSpanStartTime == Long.MAX_VALUE) {
@@ -2,6 +2,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.calltree.span.SpanAligner2;
import com.nhn.hippo.web.calltree.span.SpanPopulator;
import com.nhn.hippo.web.dao.AgentInfoDao;
import com.nhn.hippo.web.dao.SqlMetaDataDao;
@@ -28,171 +29,164 @@ 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;
@Autowired
private SqlMetaDataDao sqlMetaDataDao;
@Autowired
private SqlMetaDataDao sqlMetaDataDao;
@Autowired
private AgentInfoDao agentInfoDao;
@Autowired
private AgentInfoDao agentInfoDao;
@Override
public List<SpanAlign> selectSpan(String uuid) {
UUID id = UUID.fromString(uuid);
List<SpanBo> spans = traceDao.selectSpanAndAnnotation(id);
if (spans == null || spans.isEmpty()) {
return Collections.emptyList();
}
@Override
public List<SpanAlign> selectSpan(String uuid) {
UUID id = UUID.fromString(uuid);
List<SpanBo> spans = traceDao.selectSpanAndAnnotation(id);
if (spans == null || spans.isEmpty()) {
return Collections.emptyList();
}
List<SpanAlign> order = order(spans);
transitionApiId(order);
transitionSqlId(order);
// TODO root span not found시 row data라도 보여줘야 됨.
List<SpanAlign> order = order(spans);
transitionApiId(order);
transitionSqlId(order);
// TODO root span not found시 row data라도 보여줘야 됨.
return order;
return order;
}
}
private void transitionAnnotation(List<SpanAlign> spans, AnnotationReplacementCallback annotationReplacementCallback) {
for (SpanAlign spanAlign : spans) {
List<AnnotationBo> annotationBoList;
if (spanAlign.isSpan()) {
annotationBoList = spanAlign.getSpan().getAnnotationBoList();
annotationReplacementCallback.replacement(spanAlign, annotationBoList);
} else {
annotationBoList = spanAlign.getSubSpanBo().getAnnotationBoList();
annotationReplacementCallback.replacement(spanAlign, annotationBoList);
}
}
}
private void transitionSqlId(final List<SpanAlign> spans) {
this.transitionAnnotation(spans, new AnnotationReplacementCallback() {
@Override
public void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList) {
AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationNames.SQL_ID);
if (sqlIdAnnotation == null) {
return;
}
private void transitionAnnotation(List<SpanAlign> spans, AnnotationReplacementCallback annotationReplacementCallback) {
for (SpanAlign spanAlign : spans) {
List<AnnotationBo> annotationBoList;
if (spanAlign.isRoot()) {
annotationBoList = spanAlign.getSpan().getAnnotationBoList();
annotationReplacementCallback.replacement(spanAlign, annotationBoList);
} else {
annotationBoList = spanAlign.getSubSpanBo().getAnnotationBoList();
annotationReplacementCallback.replacement(spanAlign, annotationBoList);
}
}
}
String agentId = getAgentId(spanAlign);
long startTime = spanAlign.getSpan().getStartTime();
long agentStartTime = agentInfoDao.selectAgentInfoBeforeStartTime(agentId, startTime);
logger.info("{} Agent StartTime fonud:{}", agentId, agentStartTime);
private void transitionSqlId(final List<SpanAlign> spans) {
this.transitionAnnotation(spans, new AnnotationReplacementCallback() {
@Override
public void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList) {
AnnotationBo sqlIdAnnotation = findAnnotation(annotationBoList, AnnotationNames.SQL_ID);
if (sqlIdAnnotation == null) {
return;
}
// TODO 일단 시간까지 조회는 하지 말고 하자.
int hashCode = (Integer) sqlIdAnnotation.getValue();
List<SqlMetaDataBo> sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentId, hashCode, agentStartTime);
int size = sqlMetaDataList.size();
if (size == 0) {
AnnotationBo api = new AnnotationBo();
api.setKey(AnnotationNames.SQL_METADATA);
api.setValue("SQL-ID not found hashCode:" + hashCode);
annotationBoList.add(api);
} else if (size == 1) {
AnnotationBo sqlParamAnnotationBo = findAnnotation(annotationBoList, AnnotationNames.SQL_PARAM);
if (sqlParamAnnotationBo == null) {
AnnotationBo sqlMeta = new AnnotationBo();
sqlMeta.setKey(AnnotationNames.SQL_METADATA);
sqlMeta.setValue(sqlMetaDataList.get(0).getSql());
annotationBoList.add(sqlMeta);
String agentId = getAgentId(spanAlign);
long startTime = spanAlign.getSpan().getStartTime();
long agentStartTime = agentInfoDao.selectAgentInfoBeforeStartTime(agentId, startTime);
logger.info("{} Agent StartTime fonud:{}", agentId, agentStartTime);
AnnotationBo sql = new AnnotationBo();
sql.setKey(AnnotationNames.SQL);
sql.setValue(sqlMetaDataList.get(0).getSql());
annotationBoList.add(sql);
} else {
// merge 해야 된다.
}
} else {
AnnotationBo api = new AnnotationBo();
api.setKey(AnnotationNames.SQL_METADATA);
api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList));
annotationBoList.add(api);
}
// TODO 일단 시간까지 조회는 하지 말고 하자.
int hashCode = (Integer) sqlIdAnnotation.getValue();
List<SqlMetaDataBo> sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentId, hashCode, agentStartTime);
int size = sqlMetaDataList.size();
if (size == 0) {
AnnotationBo api = new AnnotationBo();
api.setKey(AnnotationNames.SQL_METADATA);
api.setValue("SQL-ID not found hashCode:" + hashCode);
annotationBoList.add(api);
} else if (size == 1) {
AnnotationBo sqlParamAnnotationBo = findAnnotation(annotationBoList, AnnotationNames.SQL_PARAM);
if (sqlParamAnnotationBo == null) {
AnnotationBo sqlMeta = new AnnotationBo();
sqlMeta.setKey(AnnotationNames.SQL_METADATA);
sqlMeta.setValue(sqlMetaDataList.get(0).getSql());
annotationBoList.add(sqlMeta);
}
});
}
AnnotationBo sql = new AnnotationBo();
sql.setKey(AnnotationNames.SQL);
sql.setValue(sqlMetaDataList.get(0).getSql());
annotationBoList.add(sql);
} else {
// merge 해야 된다.
}
} else {
AnnotationBo api = new AnnotationBo();
api.setKey(AnnotationNames.SQL_METADATA);
api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList));
annotationBoList.add(api);
}
private AnnotationBo findAnnotation(List<AnnotationBo> annotationBoList, String key) {
for (AnnotationBo annotationBo : annotationBoList) {
if (key.equals(annotationBo.getKey())) {
return annotationBo;
}
}
return null;
}
}
});
}
private String collisionSqlHashCodeMessage(int hashCode, List<SqlMetaDataBo> sqlMetaDataList) {
// TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음.
StringBuilder sb = new StringBuilder(64);
sb.append("Collision Sql hashCode:");
sb.append(hashCode);
sb.append('\n');
for (int i = 0; i < sqlMetaDataList.size(); i++) {
if (i != 0) {
sb.append("or\n");
}
SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i);
sb.append(sqlMetaDataBo.getSql());
}
return sb.toString();
}
private AnnotationBo findAnnotation(List<AnnotationBo> annotationBoList, String key) {
for (AnnotationBo annotationBo : annotationBoList) {
if (key.equals(annotationBo.getKey())) {
return annotationBo;
}
}
return null;
}
private String getAgentId(SpanAlign spanAlign) {
if (spanAlign.isSpan()) {
return spanAlign.getSpan().getAgentId();
} else {
return spanAlign.getSubSpanBo().getAgentId();
}
}
private String collisionSqlHashCodeMessage(int hashCode, List<SqlMetaDataBo> sqlMetaDataList) {
// TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음.
StringBuilder sb = new StringBuilder(64);
sb.append("Collision Sql hashCode:");
sb.append(hashCode);
sb.append('\n');
for (int i = 0; i < sqlMetaDataList.size(); i++) {
if (i != 0) {
sb.append("or\n");
}
SqlMetaDataBo sqlMetaDataBo = sqlMetaDataList.get(i);
sb.append(sqlMetaDataBo.getSql());
}
return sb.toString();
}
private void transitionApiId(List<SpanAlign> spans) {
this.transitionAnnotation(spans, new AnnotationReplacementCallback() {
@Override
public void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList) {
AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationNames.API_ID);
if (apiIdAnnotation == null) {
return;
}
private String getAgentId(SpanAlign spanAlign) {
if (spanAlign.isRoot()) {
return spanAlign.getSpan().getAgentId();
} else {
return spanAlign.getSubSpanBo().getAgentId();
}
}
MethodMapping methodMapping = ApiMappingTable.findMethodMapping((Integer) apiIdAnnotation.getValue());
if (methodMapping == null) {
return;
}
String className = methodMapping.getClassMapping().getClassName();
String methodName = methodMapping.getMethodName();
String[] parameterType = methodMapping.getParameterType();
String[] parameterName = methodMapping.getParameterName();
String args = ApiUtils.mergeParameterVariableNameDescription(parameterType, parameterName);
AnnotationBo api = new AnnotationBo();
api.setKey("API");
api.setValue(className + "." + methodName + args);
annotationBoList.add(api);
}
});
}
private void transitionApiId(List<SpanAlign> spans) {
this.transitionAnnotation(spans, new AnnotationReplacementCallback() {
@Override
public void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList) {
public static interface AnnotationReplacementCallback {
void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList);
}
AnnotationBo apiIdAnnotation = findAnnotation(annotationBoList, AnnotationNames.API_ID);
if (apiIdAnnotation == null) {
return;
}
private List<SpanAlign> order(List<SpanBo> spans) {
SpanAligner2 spanAligner = new SpanAligner2(spans);
return spanAligner.sort();
MethodMapping methodMapping = ApiMappingTable.findMethodMapping((Integer) apiIdAnnotation.getValue());
if (methodMapping == null) {
return;
}
String className = methodMapping.getClassMapping().getClassName();
String methodName = methodMapping.getMethodName();
String[] parameterType = methodMapping.getParameterType();
String[] parameterName = methodMapping.getParameterName();
String args = ApiUtils.mergeParameterVariableNameDescription(parameterType, parameterName);
AnnotationBo api = new AnnotationBo();
api.setKey("API");
api.setValue(className + "." + methodName + args);
annotationBoList.add(api);
}
});
}
public static interface AnnotationReplacementCallback {
void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList);
}
private List<SpanAlign> order(List<SpanBo> spans) {
SpanAligner spanAligner = new SpanAligner(spans);
List<SpanAlign> sort = spanAligner.sort();
if (sort.size() != spans.size()) {
// TODO 중간 노드 데이터 분실 ? 혹은 잘못된 데이터 생성?
logger.warn("span node not complete! spans:{}, sort{}", spans, sort);
}
SpanPopulator spanPopulator = new SpanPopulator(sort);
List<SpanAlign> populatedList = spanPopulator.populateSubSpan();
return populatedList;
}
/*
* SpanAligner spanAligner = new SpanAligner(spans); List<SpanAlign> sort = spanAligner.sort(); if (sort.size() != spans.size()) { // TODO 중간 노드 데이터 분실 ? 혹은 잘못된 데이터 생성? logger.warn("span node not complete! spans:{}, sort{}", spans, sort); } SpanPopulator spanPopulator = new SpanPopulator(sort); List<SpanAlign> populatedList = spanPopulator.populateSubSpan(); return populatedList;
*/
}
}
@@ -78,7 +78,7 @@ public class RecordSet {
boolean marked = false;
for (SpanAlign sa : spanAligns) {
if (sa.isRoot()) {
if (sa.isSpan()) {
SpanBo span = sa.getSpan();
AnnotationUtils.sortAnnotationListByKey(span);
String method = (String) AnnotationUtils.getDisplayMethod(span);