From 0131a35dec61c87217600f7aed59ced9f005a418 Mon Sep 17 00:00:00 2001 From: wusheng Date: Wed, 2 Mar 2016 15:06:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BA=8F=E5=88=97=E5=8C=96?= =?UTF-8?q?=E5=92=8C=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chainbuild/entity/TraceSpanNode.java | 54 +++++++++++++--- .../chainbuild/entity/TraceSpanTree.java | 62 ++++++++++++++----- .../TraceSpanTreeNotFountException.java | 13 ++++ 3 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/exception/TraceSpanTreeNotFountException.java diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanNode.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanNode.java index d0c4430d3..37c27604b 100644 --- a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanNode.java +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanNode.java @@ -1,5 +1,8 @@ package com.ai.cloud.skywalking.analysis.chainbuild.entity; +import java.util.List; + +import com.ai.cloud.skywalking.analysis.chainbuild.exception.TraceSpanTreeNotFountException; import com.ai.cloud.skywalking.analysis.chainbuild.exception.TraceSpanTreeSerializeException; import com.ai.cloud.skywalking.analysis.chainbuild.util.StringUtil; import com.ai.cloud.skywalking.analysis.chainbuild.util.TokenGenerator; @@ -7,8 +10,6 @@ import com.ai.cloud.skywalking.protocol.CallType; import com.ai.cloud.skywalking.protocol.Span; import com.google.gson.annotations.Expose; -import java.util.List; - public class TraceSpanNode { protected TraceSpanNode prev = null; @@ -88,6 +89,13 @@ public class TraceSpanNode { @Expose protected String applicationId = ""; + /** + * Warning: call this constructor ONLY by gson for deserialize + */ + public TraceSpanNode(){ + + } + public TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, Span span, List spanContainer) { this(parent, sub, prev, next, spanContainer); this.visualNode = false; @@ -170,19 +178,47 @@ public class TraceSpanNode { } } - public TraceSpanNode prev() { + public TraceSpanNode prev(TraceSpanTree tree) throws TraceSpanTreeNotFountException { + if(prev == null){ + if(prevNodeRefToken == null){ + throw new TraceSpanTreeNotFountException(getDesc() + " unexpected prev== null and prevNodeRefToken==null"); + }else{ + prev = tree.findNode(prevNodeRefToken); + } + } return prev; } - public TraceSpanNode next() { + public TraceSpanNode next(TraceSpanTree tree) throws TraceSpanTreeNotFountException { + if(next == null){ + if(nextNodeRefToken == null){ + throw new TraceSpanTreeNotFountException(getDesc() + " unexpected next== null and nextNodeRefToken==null"); + }else{ + next = tree.findNode(nextNodeRefToken); + } + } return next; } - public TraceSpanNode parent() { + public TraceSpanNode parent(TraceSpanTree tree) throws TraceSpanTreeNotFountException { + if(parent == null){ + if(parentNodeRefToken == null){ + throw new TraceSpanTreeNotFountException(getDesc() + " unexpected parent== null and parentNodeRefToken==null"); + }else{ + parent = tree.findNode(parentNodeRefToken); + } + } return parent; } - public TraceSpanNode sub() { + public TraceSpanNode sub(TraceSpanTree tree) throws TraceSpanTreeNotFountException { + if(sub == null){ + if(subNodeRefToken == null){ + throw new TraceSpanTreeNotFountException(getDesc() + " unexpected sub== null and subNodeRefToken==null"); + }else{ + sub = tree.findNode(subNodeRefToken); + } + } return sub; } @@ -244,10 +280,14 @@ public class TraceSpanNode { public String getNodeRefToken() throws TraceSpanTreeSerializeException { if (StringUtil.isBlank(nodeRefToken)) { - throw new TraceSpanTreeSerializeException("parentLevel=" + parentLevel + ", levelId=" + levelId + ", viewPointId=" + viewPointId + ", node ref token is null."); + throw new TraceSpanTreeSerializeException(getDesc() + " ref token is null."); } return nodeRefToken; } + + private String getDesc(){ + return "Node[parentLevel=" + parentLevel + ", levelId=" + levelId + ", viewPointId=" + viewPointId + "]"; + } void serializeRef() throws TraceSpanTreeSerializeException { if (prev != null) { 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 1f61e9496..4338c9f33 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 @@ -1,6 +1,21 @@ package com.ai.cloud.skywalking.analysis.chainbuild.entity; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.io.Writable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.ai.cloud.skywalking.analysis.chainbuild.exception.BuildTraceSpanTreeException; +import com.ai.cloud.skywalking.analysis.chainbuild.exception.TraceSpanTreeNotFountException; import com.ai.cloud.skywalking.analysis.chainbuild.exception.TraceSpanTreeSerializeException; import com.ai.cloud.skywalking.analysis.chainbuild.util.StringUtil; import com.ai.cloud.skywalking.analysis.chainbuild.util.TokenGenerator; @@ -9,34 +24,30 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.gson.annotations.Expose; import com.google.gson.reflect.TypeToken; -import org.apache.hadoop.io.Writable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; public class TraceSpanTree implements Writable { private Logger logger = LoggerFactory.getLogger(TraceSpanTree.class); + @Expose private String userId = null; + @Expose private String cid; + @Expose private TraceSpanNode treeRoot; + @Expose private List spanContainer = new ArrayList(); + + private Map traceSpanNodeMap = new HashMap(); public TraceSpanTree() { } - public String build(List spanList) throws BuildTraceSpanTreeException { + public String build(List spanList) throws BuildTraceSpanTreeException, TraceSpanTreeNotFountException { if (spanList.size() == 0) { throw new BuildTraceSpanTreeException("spanList is empty."); } @@ -62,7 +73,7 @@ public class TraceSpanTree implements Writable { return cid; } - private void build(Span span) throws BuildTraceSpanTreeException { + private void build(Span span) throws BuildTraceSpanTreeException, TraceSpanTreeNotFountException { if (userId == null && span.getUserId() != null) { userId = span.getUserId(); } @@ -76,7 +87,10 @@ public class TraceSpanTree implements Writable { if (span.getLevelId() > 0) { TraceSpanNode foundNode = findNodeAndCreateVisualNodeIfNess( span.getParentLevel(), span.getLevelId() - 1); - new TraceSpanNode(null, null, foundNode, foundNode.next(), span, spanContainer); + /** + * 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 @@ -91,13 +105,16 @@ public class TraceSpanTree implements Writable { 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) { + String parentLevelId, int levelId) throws TraceSpanTreeNotFountException { String levelDesc = StringUtil.isBlank(parentLevelId) ? (levelId + "") : (parentLevelId + "." + levelId); String[] levelArray = levelDesc.split("\\."); @@ -108,7 +125,7 @@ public class TraceSpanTree implements Writable { int currentLevelInt = Integer.parseInt(currentLevel); for (int i = 0; i < currentLevelInt; i++) { if (currentNode.hasNext()) { - currentNode = currentNode.next(); + currentNode = currentNode.next(this); } else { // create visual next node currentNode = new VisualTraceSpanNode(null, null, @@ -118,7 +135,7 @@ public class TraceSpanTree implements Writable { contextParentLevelId = contextParentLevelId == "" ? ("" + currentLevelInt) : (contextParentLevelId + "." + currentLevelInt); if (currentNode.hasSub()) { - currentNode = currentNode.sub(); + currentNode = currentNode.sub(this); } else { // create visual sub node currentNode = new VisualTraceSpanNode(currentNode, null, null, @@ -153,6 +170,14 @@ public class TraceSpanTree implements Writable { 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."); + } + } @Override public void write(DataOutput out) throws IOException { @@ -174,6 +199,9 @@ public class TraceSpanTree implements Writable { 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); } diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/exception/TraceSpanTreeNotFountException.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/exception/TraceSpanTreeNotFountException.java new file mode 100644 index 000000000..9bff13a02 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/exception/TraceSpanTreeNotFountException.java @@ -0,0 +1,13 @@ +package com.ai.cloud.skywalking.analysis.chainbuild.exception; + +public class TraceSpanTreeNotFountException extends Exception { + private static final long serialVersionUID = 5559441397011866237L; + + public TraceSpanTreeNotFountException(String msg){ + super(msg); + } + + public TraceSpanTreeNotFountException(String msg, Exception cause){ + super(msg, cause); + } +} -- GitLab