diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/ChainBuildMapper.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/ChainBuildMapper.java index bf3f36fed..9daf3e75a 100644 --- a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/ChainBuildMapper.java +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/ChainBuildMapper.java @@ -45,7 +45,7 @@ public class ChainBuildMapper extends TableMapper { TraceSpanTree tree = new TraceSpanTree(); tree.build(spanList); - context.write(new Text(tree.getTreeRoot().getNodeRefToken()), tree); + context.write(new Text(tree.getCid()), tree); } catch (Throwable e) { logger.error("Failed to mapper call chain[" + key.toString() + "]", e); diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanTree.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanTree.java index 4338c9f33..e5dc68317 100644 --- a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanTree.java +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanTree.java @@ -4,13 +4,16 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.hadoop.io.Writable; +import org.mortbay.log.Log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,186 +31,223 @@ import com.google.gson.annotations.Expose; import com.google.gson.reflect.TypeToken; public class TraceSpanTree implements Writable { - private Logger logger = LoggerFactory.getLogger(TraceSpanTree.class); + private Logger logger = LoggerFactory.getLogger(TraceSpanTree.class); - @Expose - private String userId = null; + @Expose + private String userId = null; - @Expose - private String cid; + @Expose + private String cid; - @Expose - private TraceSpanNode treeRoot; + @Expose + private TraceSpanNode treeRoot; - @Expose - private List spanContainer = new ArrayList(); - - private Map traceSpanNodeMap = new HashMap(); + @Expose + private List spanContainer = new ArrayList(); - public TraceSpanTree() { - } + private Map traceSpanNodeMap = new HashMap(); - public String build(List spanList) throws BuildTraceSpanTreeException, TraceSpanTreeNotFountException { - if (spanList.size() == 0) { - throw new BuildTraceSpanTreeException("spanList is empty."); - } + public TraceSpanTree() { + } - Collections.sort(spanList, new Comparator() { - @Override - public int compare(Span span1, Span span2) { - String span1TraceLevel = span1.getParentLevel() + "." - + span1.getLevelId(); - String span2TraceLevel = span2.getParentLevel() + "." - + span2.getLevelId(); - return span1TraceLevel.compareTo(span2TraceLevel); - } - }); - cid = generateChainToken(spanList.get(0)); - treeRoot = new TraceSpanNode(null, null, null, null, spanList.get(0), spanContainer); - if (spanList.size() > 1) { - for (int i = 1; i < spanList.size(); i++) { - this.build(spanList.get(i)); - } - } + public String build(List spanList) + throws BuildTraceSpanTreeException, TraceSpanTreeNotFountException { + if (spanList.size() == 0) { + throw new BuildTraceSpanTreeException("spanList is empty."); + } - return cid; - } + Collections.sort(spanList, new Comparator() { + @Override + public int compare(Span span1, Span span2) { + String span1TraceLevel = span1.getParentLevel() + "." + + span1.getLevelId(); + String span2TraceLevel = span2.getParentLevel() + "." + + span2.getLevelId(); + return span1TraceLevel.compareTo(span2TraceLevel); + } + }); + Span span = spanList.get(0); + if (!StringUtil.isBlank(span.getUserId())) { + userId = span.getUserId(); + } else { + throw new BuildTraceSpanTreeException( + "spanList[0] 's userId is null"); + } + cid = generateCID(spanList.get(0)); + treeRoot = new TraceSpanNode(null, null, null, null, spanList.get(0), + spanContainer); + if (spanList.size() > 1) { + for (int i = 1; i < spanList.size(); i++) { + this.build(spanList.get(i)); + } + } - private void build(Span span) throws BuildTraceSpanTreeException, TraceSpanTreeNotFountException { - if (userId == null && span.getUserId() != null) { - userId = span.getUserId(); - } + return cid; + } - TraceSpanNode clientOrServerNode = findNodeAndCreateVisualNodeIfNess( - span.getParentLevel(), span.getLevelId()); - if (clientOrServerNode != null) { - clientOrServerNode.mergeSpan(span); - } + private void build(Span span) throws BuildTraceSpanTreeException, + TraceSpanTreeNotFountException { + if (userId == null && !StringUtil.isBlank(span.getUserId())) { + userId = span.getUserId(); + } - if (span.getLevelId() > 0) { - TraceSpanNode foundNode = findNodeAndCreateVisualNodeIfNess( - span.getParentLevel(), span.getLevelId() - 1); - /** - * Create node between foundNode and foundNode.next(maybe foundNode.next == null) - */ - new TraceSpanNode(null, null, foundNode, foundNode.next(this), span, spanContainer); - } else { - /** - * levelId=0 find for parent level if parentLevelId = 0.0.1 then - * find node[parentLevelId=0.0,levelId=1] - */ - String parentLevel = span.getParentLevel(); - int idx = parentLevel.lastIndexOf("\\."); - if (idx < 0) { - throw new BuildTraceSpanTreeException("parentLevel=" - + parentLevel + " is unexpected."); - } - TraceSpanNode foundNode = findNodeAndCreateVisualNodeIfNess( - parentLevel.substring(0, idx), - Integer.parseInt(parentLevel.substring(idx + 1))); - /** - * Create sub node of using span data. FoundNode is parent node. - */ - new TraceSpanNode(foundNode, null, null, null, span, spanContainer); + TraceSpanNode clientOrServerNode = findNodeAndCreateVisualNodeIfNess( + span.getParentLevel(), span.getLevelId()); + if (clientOrServerNode != null) { + clientOrServerNode.mergeSpan(span); + } - } - } + if (span.getLevelId() > 0) { + TraceSpanNode foundNode = findNodeAndCreateVisualNodeIfNess( + span.getParentLevel(), span.getLevelId() - 1); + /** + * Create node between foundNode and foundNode.next(maybe + * foundNode.next == null) + */ + new TraceSpanNode(null, null, foundNode, foundNode.next(this), + span, spanContainer); + } else { + /** + * levelId=0 find for parent level if parentLevelId = 0.0.1 then + * find node[parentLevelId=0.0,levelId=1] + */ + String parentLevel = span.getParentLevel(); + int idx = parentLevel.lastIndexOf("\\."); + if (idx < 0) { + throw new BuildTraceSpanTreeException("parentLevel=" + + parentLevel + " is unexpected."); + } + TraceSpanNode foundNode = findNodeAndCreateVisualNodeIfNess( + parentLevel.substring(0, idx), + Integer.parseInt(parentLevel.substring(idx + 1))); + /** + * Create sub node of using span data. FoundNode is parent node. + */ + new TraceSpanNode(foundNode, null, null, null, span, spanContainer); - private TraceSpanNode findNodeAndCreateVisualNodeIfNess( - String parentLevelId, int levelId) throws TraceSpanTreeNotFountException { - String levelDesc = StringUtil.isBlank(parentLevelId) ? (levelId + "") - : (parentLevelId + "." + levelId); - String[] levelArray = levelDesc.split("\\."); + } + } - TraceSpanNode currentNode = treeRoot; - String contextParentLevelId = ""; - for (String currentLevel : levelArray) { - int currentLevelInt = Integer.parseInt(currentLevel); - for (int i = 0; i < currentLevelInt; i++) { - if (currentNode.hasNext()) { - currentNode = currentNode.next(this); - } else { - // create visual next node - currentNode = new VisualTraceSpanNode(null, null, - currentNode, null, contextParentLevelId, i, spanContainer); - } - } - contextParentLevelId = contextParentLevelId == "" ? ("" + currentLevelInt) - : (contextParentLevelId + "." + currentLevelInt); - if (currentNode.hasSub()) { - currentNode = currentNode.sub(this); - } else { - // create visual sub node - currentNode = new VisualTraceSpanNode(currentNode, null, null, - null, contextParentLevelId, 0, spanContainer); - } - } + private TraceSpanNode findNodeAndCreateVisualNodeIfNess( + String parentLevelId, int levelId) + throws TraceSpanTreeNotFountException { + String levelDesc = StringUtil.isBlank(parentLevelId) ? (levelId + "") + : (parentLevelId + "." + levelId); + String[] levelArray = levelDesc.split("\\."); - return currentNode; - } + TraceSpanNode currentNode = treeRoot; + String contextParentLevelId = ""; + for (String currentLevel : levelArray) { + int currentLevelInt = Integer.parseInt(currentLevel); + for (int i = 0; i < currentLevelInt; i++) { + if (currentNode.hasNext()) { + currentNode = currentNode.next(this); + } else { + // create visual next node + currentNode = new VisualTraceSpanNode(null, null, + currentNode, null, contextParentLevelId, i, + spanContainer); + } + } + contextParentLevelId = contextParentLevelId == "" ? ("" + currentLevelInt) + : (contextParentLevelId + "." + currentLevelInt); + if (currentNode.hasSub()) { + currentNode = currentNode.sub(this); + } else { + // create visual sub node + currentNode = new VisualTraceSpanNode(currentNode, null, null, + null, contextParentLevelId, 0, spanContainer); + } + } - private String generateChainToken(Span level0Span) - throws BuildTraceSpanTreeException { - if (StringUtil.isBlank(level0Span.getParentLevel()) - && level0Span.getLevelId() == 0) { - StringBuilder chainTokenDesc = new StringBuilder(); - chainTokenDesc.append(level0Span.getViewPointId()); - return TokenGenerator.generateCID(chainTokenDesc.toString()); - } else { - throw new BuildTraceSpanTreeException("tid:" - + level0Span.getTraceId() + " level0 span data is illegal"); - } - } + return currentNode; + } + private String generateCID(Span level0Span) + throws BuildTraceSpanTreeException { + if (StringUtil.isBlank(level0Span.getParentLevel()) + && level0Span.getLevelId() == 0) { + StringBuilder chainTokenDesc = new StringBuilder(); + chainTokenDesc.append(userId).append("_"); + chainTokenDesc.append(level0Span.getViewPointId()); + return getTSBySpanTraceId(level0Span) + "_" + TokenGenerator.generateCID(chainTokenDesc.toString()); + } else { + throw new BuildTraceSpanTreeException("tid:" + + level0Span.getTraceId() + " level0 span data is illegal"); + } + } - private void beforeSerialize() throws TraceSpanTreeSerializeException { - for (TraceSpanNode treeNode : spanContainer) { - treeNode.serializeRef(); - } - } + private static String getTSBySpanTraceId(Span span) + throws BuildTraceSpanTreeException { + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(Long.parseLong(span.getTraceId().split( + "\\.")[2]))); + return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1); + } catch (Throwable t) { + throw new BuildTraceSpanTreeException("tid:" + span.getTraceId() + + " is illegal."); + } + } - public String serialize() throws TraceSpanTreeSerializeException { - beforeSerialize(); - return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(this); - } - - TraceSpanNode findNode(String nodeRefToken) throws TraceSpanTreeNotFountException{ - if(traceSpanNodeMap.containsKey(nodeRefToken)){ - return traceSpanNodeMap.get(nodeRefToken); - }else{ - throw new TraceSpanTreeNotFountException("nodeRefToken=" + nodeRefToken + " not found."); - } - } + private void beforeSerialize() throws TraceSpanTreeSerializeException { + for (TraceSpanNode treeNode : spanContainer) { + treeNode.serializeRef(); + } + } - @Override - public void write(DataOutput out) throws IOException { - try { - out.write(serialize().getBytes()); - } catch (TraceSpanTreeSerializeException e) { - logger.error("Failed to serialize Chain Id[" + cid + "]", e); - } - } + public String serialize() throws TraceSpanTreeSerializeException { + beforeSerialize(); + return new GsonBuilder().excludeFieldsWithoutExposeAnnotation() + .create().toJson(this); + } - @Override - public void readFields(DataInput in) throws IOException { - String value = in.readLine(); - try { - JsonObject jsonObject = (JsonObject) new JsonParser().parse(value); - userId = jsonObject.get("userId").getAsString(); - cid = jsonObject.get("cid").getAsString(); - treeRoot = new Gson().fromJson(jsonObject.get("treeRoot"), TraceSpanNode.class); - spanContainer = new Gson().fromJson(jsonObject.get("spanContainer"), - new TypeToken>() { - }.getType()); - for(TraceSpanNode node : spanContainer){ - traceSpanNodeMap.put(node.getNodeRefToken(), node); - } - } catch (Exception e) { - logger.error("Failed to parse the value[" + value + "] to TraceSpanTree Object", e); - } - } + TraceSpanNode findNode(String nodeRefToken) + throws TraceSpanTreeNotFountException { + if (traceSpanNodeMap.containsKey(nodeRefToken)) { + return traceSpanNodeMap.get(nodeRefToken); + } else { + throw new TraceSpanTreeNotFountException("nodeRefToken=" + + nodeRefToken + " not found."); + } + } - public TraceSpanNode getTreeRoot() { - return treeRoot; - } + @Override + public void write(DataOutput out) throws IOException { + try { + out.write(serialize().getBytes()); + } catch (TraceSpanTreeSerializeException e) { + logger.error("Failed to serialize Chain Id[" + cid + "]", e); + } + } + + @Override + public void readFields(DataInput in) throws IOException { + String value = in.readLine(); + try { + JsonObject jsonObject = (JsonObject) new JsonParser().parse(value); + userId = jsonObject.get("userId").getAsString(); + cid = jsonObject.get("cid").getAsString(); + treeRoot = new Gson().fromJson(jsonObject.get("treeRoot"), + TraceSpanNode.class); + spanContainer = new Gson().fromJson( + jsonObject.get("spanContainer"), + new TypeToken>() { + }.getType()); + for (TraceSpanNode node : spanContainer) { + traceSpanNodeMap.put(node.getNodeRefToken(), node); + } + } catch (Exception e) { + logger.error("Failed to parse the value[" + value + + "] to TraceSpanTree Object", e); + } + } + + public TraceSpanNode getTreeRoot() { + return treeRoot; + } + + public String getCid() { + return cid; + } } diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/VisualTraceSpanNode.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/VisualTraceSpanNode.java index 6d155f528..4b589b74b 100644 --- a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/VisualTraceSpanNode.java +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/VisualTraceSpanNode.java @@ -2,6 +2,8 @@ package com.ai.cloud.skywalking.analysis.chainbuild.entity; import java.util.List; +import com.ai.cloud.skywalking.analysis.chainbuild.util.StringUtil; + public class VisualTraceSpanNode extends TraceSpanNode { protected VisualTraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, @@ -9,7 +11,13 @@ public class VisualTraceSpanNode extends TraceSpanNode { int levelId, List spanContainer) { super(parent, sub, prev, next, parentLevelId, levelId, spanContainer); - //TODO: to set nodeToken + /**set visual node token.
+ * for example:
+ * VisualNode[0.0]
+ * VisualNode[0.0.1]
+ * etc.
+ */ + nodeRefToken = "VisualNode[" + (StringUtil.isBlank(parentLevelId) ? "": nodeRefToken + ".") + levelId + "]"; }