From 6f08371c5da109487bdde9990fd6258463f33eef Mon Sep 17 00:00:00 2001 From: ascrutae Date: Wed, 2 Mar 2016 14:03:51 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=B7=BB=E5=8A=A0TraceSpanTree=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E6=96=B9=E6=B3=95=202.=20=E5=B0=86Mapper?= =?UTF-8?q?=E7=9A=84Keyout=E5=AF=B9=E8=B1=A1=E4=BF=AE=E6=94=B9=E6=88=90Tra?= =?UTF-8?q?ceSpanTree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/chainbuild/ChainBuildMapper.java | 82 ++-- .../chainbuild/entity/TraceSpanNode.java | 431 +++++++++--------- .../chainbuild/entity/TraceSpanTree.java | 310 +++++++------ 3 files changed, 433 insertions(+), 390 deletions(-) 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 fbac6e728..bf3f36fed 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 @@ -1,9 +1,9 @@ package com.ai.cloud.skywalking.analysis.chainbuild; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - +import com.ai.cloud.skywalking.analysis.chainbuild.entity.TraceSpanTree; +import com.ai.cloud.skywalking.analysis.chainbuild.util.VersionIdentifier; +import com.ai.cloud.skywalking.analysis.config.ConfigInitializer; +import com.ai.cloud.skywalking.protocol.Span; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; @@ -13,42 +13,42 @@ import org.apache.hadoop.io.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.ai.cloud.skywalking.analysis.chainbuild.entity.TraceSpanTree; -import com.ai.cloud.skywalking.analysis.chainbuild.util.VersionIdentifier; -import com.ai.cloud.skywalking.analysis.config.ConfigInitializer; -import com.ai.cloud.skywalking.protocol.Span; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ChainBuildMapper extends TableMapper { + private Logger logger = LoggerFactory + .getLogger(ChainBuildMapper.class); + + @Override + protected void setup(Context context) throws IOException, + InterruptedException { + ConfigInitializer.initialize(); + } + + @Override + protected void map(ImmutableBytesWritable key, Result value, Context context) + throws IOException, InterruptedException { + if (!VersionIdentifier.enableAnaylsis(Bytes.toString(key.get()))) { + return; + } + + try { + List spanList = new ArrayList(); + for (Cell cell : value.rawCells()) { + Span span = new Span(Bytes.toString(cell.getValueArray(), + cell.getValueOffset(), cell.getValueLength())); + spanList.add(span); + + } -public class ChainBuildMapper extends TableMapper { - private Logger logger = LoggerFactory - .getLogger(ChainBuildMapper.class); - - @Override - protected void setup(Context context) throws IOException, - InterruptedException { - ConfigInitializer.initialize(); - } - - @Override - protected void map(ImmutableBytesWritable key, Result value, Context context) - throws IOException, InterruptedException { - if(!VersionIdentifier.enableAnaylsis(Bytes.toString(key.get()))){ - return; - } - - try { - List spanList = new ArrayList(); - for (Cell cell : value.rawCells()) { - Span span = new Span(Bytes.toString(cell.getValueArray(), - cell.getValueOffset(), cell.getValueLength())); - spanList.add(span); - - } - - TraceSpanTree tree = new TraceSpanTree(); - tree.build(spanList); - } catch (Throwable e) { - logger.error("Failed to mapper call chain[" + key.toString() + "]", - e); - } - } + TraceSpanTree tree = new TraceSpanTree(); + tree.build(spanList); + context.write(new Text(tree.getTreeRoot().getNodeRefToken()), 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/TraceSpanNode.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/chainbuild/entity/TraceSpanNode.java index 43a4183ee..32fca805a 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,246 +1,249 @@ package com.ai.cloud.skywalking.analysis.chainbuild.entity; -import java.util.List; - 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; import com.ai.cloud.skywalking.protocol.CallType; import com.ai.cloud.skywalking.protocol.Span; +import java.util.List; + public class TraceSpanNode { - protected TraceSpanNode prev = null; - - protected TraceSpanNode next = null; - - protected TraceSpanNode parent = null; - - protected TraceSpanNode sub = null; - - protected String prevNodeRefToken = null; - - protected String nextNodeRefToken = null; - - protected String parentNodeRefToken = null; - - protected String subNodeRefToken = null; - - protected String nodeRefToken = null; - - protected boolean visualNode = true; - - protected String parentLevel; - - protected int levelId; - - protected String viewPointId = ""; - - protected long cost = 0; - - protected long callTimes = 0; - + protected TraceSpanNode prev = null; + + protected TraceSpanNode next = null; + + protected TraceSpanNode parent = null; + + protected TraceSpanNode sub = null; + + protected String prevNodeRefToken = null; + + protected String nextNodeRefToken = null; + + protected String parentNodeRefToken = null; + + protected String subNodeRefToken = null; + + protected String nodeRefToken = null; + + protected boolean visualNode = true; + + protected String parentLevel; + + protected int levelId; + + protected String viewPointId = ""; + + protected long cost = 0; + + protected long callTimes = 0; + /** * 节点调用的状态
* 0:成功
* 1:异常
* 异常判断原则:代码产生exception,并且此exception不在忽略列表中 */ - protected byte statusCode = 0; - + protected byte statusCode = 0; + /** * 节点调用的错误堆栈
* 堆栈以JAVA的exception为主要判断依据 */ - protected String exceptionStack; + protected String exceptionStack; /** * 节点类型描述
* 已字符串的形式描述
* 如:java,dubbo等 */ - protected String spanType = ""; - + protected String spanType = ""; + /** * 节点调用过程中的业务字段
* 如:业务系统设置的订单号,SQL语句等 */ - protected String businessKey = ""; - + protected String businessKey = ""; + /** * 节点调用所在的系统逻辑名称
* 由授权文件指定 */ - protected String applicationId = ""; - - public TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, Span span, List spanContainer) { - this(parent, sub, prev, next, spanContainer); - this.visualNode = false; - this.parentLevel = span.getParentLevel(); - this.levelId = span.getLevelId(); - this.viewPointId = span.getViewPointId(); - this.cost = span.getCost(); - this.callTimes = 1; - this.statusCode = span.getStatusCode(); - if(span.isReceiver()){ - this.exceptionStack = "server stack:"; - }else{ - this.exceptionStack = "client stack:"; - } - this.exceptionStack += span.getExceptionStack(); - this.spanType = span.getSpanType(); - this.businessKey = span.getBusinessKey(); - this.applicationId = span.getApplicationId(); - - //TODO: to set nodeToken - } - - protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, List spanContainer){ - this.visualNode = true; - this.setParent(parent); - if(parent != null){ - parent.setSub(this); - } - this.setSub(sub); - if(sub != null){ - sub.setParent(this); - } - this.setPrev(prev); - if(prev != null){ - prev.setNext(this); - } - this.setNext(next); - if(next != null){ - next.setPrev(this); - } - spanContainer.add(this); - } - - protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, String parentLevelId, int levelId, List spanContainer){ - this(parent, sub, prev, next, spanContainer); - this.parentLevel = parentLevelId; - this.levelId = levelId; - this.callTimes = 0; - } - - boolean hasNext(){ - if(this.next != null){ - return true; - }else{ - return false; - } - } - - boolean hasSub(){ - if(this.sub != null){ - return true; - }else{ - return false; - } - } - - void mergeSpan(Span span){ - if(CallType.convert(span.getCallType()) == CallType.ASYNC){ - this.cost += span.getCost(); - } - if(span.getStatusCode() != 0 && !StringUtil.isBlank(span.getExceptionStack())){ - if(span.isReceiver()){ - this.exceptionStack += "server stack:"; - }else{ - this.exceptionStack += "client stack:"; - } - this.exceptionStack += span.getExceptionStack(); - } - } - - public TraceSpanNode prev() { - return prev; - } - - public TraceSpanNode next() { - return next; - } - - public TraceSpanNode parent() { - return parent; - } - - public TraceSpanNode sub() { - return sub; - } - - public void setPrev(TraceSpanNode prev) { - this.prev = prev; - } - - public void setNext(TraceSpanNode next) { - this.next = next; - } - - public void setParent(TraceSpanNode parent) { - this.parent = parent; - } - - public void setSub(TraceSpanNode sub) { - this.sub = sub; - } - - public boolean isVisualNode() { - return visualNode; - } - - public String getParentLevel() { - return parentLevel; - } - - public int getLevelId() { - return levelId; - } - - public String getViewPointId() { - return viewPointId; - } - - public long getCost() { - return cost; - } - - public byte getStatusCode() { - return statusCode; - } - - public String getExceptionStack() { - return exceptionStack; - } - - public String getSpanType() { - return spanType; - } - - public String getBusinessKey() { - return businessKey; - } - - public String getApplicationId() { - return applicationId; - } - - public String getNodeRefToken() throws TraceSpanTreeSerializeException { - if(StringUtil.isBlank(nodeRefToken)){ - throw new TraceSpanTreeSerializeException("parentLevel=" + parentLevel + ", levelId=" + levelId + ", viewPointId=" + viewPointId + ", node ref token is null."); - } - return nodeRefToken; - } - - void serializeRef() throws TraceSpanTreeSerializeException{ - if(prev != null){ - prevNodeRefToken = prev.getNodeRefToken(); - } - if(parent != null){ - parentNodeRefToken = parent.getNodeRefToken(); - } - if(next != null){ - nextNodeRefToken = next.getNodeRefToken(); - } - if(sub != null){ - subNodeRefToken = sub.getNodeRefToken(); - } - } + protected String applicationId = ""; + + public TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, Span span, List spanContainer) { + this(parent, sub, prev, next, spanContainer); + this.visualNode = false; + this.parentLevel = span.getParentLevel(); + this.levelId = span.getLevelId(); + this.viewPointId = span.getViewPointId(); + this.cost = span.getCost(); + this.callTimes = 1; + this.statusCode = span.getStatusCode(); + if (span.isReceiver()) { + this.exceptionStack = "server stack:"; + } else { + this.exceptionStack = "client stack:"; + } + this.exceptionStack += span.getExceptionStack(); + this.spanType = span.getSpanType(); + this.businessKey = span.getBusinessKey(); + this.applicationId = span.getApplicationId(); + + //nodeToken : MD5(parentLevelId + levelId + viewpoint) + nodeRefToken = TokenGenerator.generateNodeToken(parentLevel + "-" + levelId + "-" + viewPointId); + + } + + protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, List spanContainer) { + this.visualNode = true; + this.setParent(parent); + if (parent != null) { + parent.setSub(this); + } + this.setSub(sub); + if (sub != null) { + sub.setParent(this); + } + this.setPrev(prev); + if (prev != null) { + prev.setNext(this); + } + this.setNext(next); + if (next != null) { + next.setPrev(this); + } + spanContainer.add(this); + } + + protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, String parentLevelId, int levelId, List spanContainer) { + this(parent, sub, prev, next, spanContainer); + this.parentLevel = parentLevelId; + this.levelId = levelId; + this.callTimes = 0; + } + + boolean hasNext() { + if (this.next != null) { + return true; + } else { + return false; + } + } + + boolean hasSub() { + if (this.sub != null) { + return true; + } else { + return false; + } + } + + void mergeSpan(Span span) { + if (CallType.convert(span.getCallType()) == CallType.ASYNC) { + this.cost += span.getCost(); + } + if (span.getStatusCode() != 0 && !StringUtil.isBlank(span.getExceptionStack())) { + if (span.isReceiver()) { + this.exceptionStack += "server stack:"; + } else { + this.exceptionStack += "client stack:"; + } + this.exceptionStack += span.getExceptionStack(); + } + } + + public TraceSpanNode prev() { + return prev; + } + + public TraceSpanNode next() { + return next; + } + + public TraceSpanNode parent() { + return parent; + } + + public TraceSpanNode sub() { + return sub; + } + + public void setPrev(TraceSpanNode prev) { + this.prev = prev; + } + + public void setNext(TraceSpanNode next) { + this.next = next; + } + + public void setParent(TraceSpanNode parent) { + this.parent = parent; + } + + public void setSub(TraceSpanNode sub) { + this.sub = sub; + } + + public boolean isVisualNode() { + return visualNode; + } + + public String getParentLevel() { + return parentLevel; + } + + public int getLevelId() { + return levelId; + } + + public String getViewPointId() { + return viewPointId; + } + + public long getCost() { + return cost; + } + + public byte getStatusCode() { + return statusCode; + } + + public String getExceptionStack() { + return exceptionStack; + } + + public String getSpanType() { + return spanType; + } + + public String getBusinessKey() { + return businessKey; + } + + public String getApplicationId() { + return applicationId; + } + + public String getNodeRefToken() throws TraceSpanTreeSerializeException { + if (StringUtil.isBlank(nodeRefToken)) { + throw new TraceSpanTreeSerializeException("parentLevel=" + parentLevel + ", levelId=" + levelId + ", viewPointId=" + viewPointId + ", node ref token is null."); + } + return nodeRefToken; + } + + void serializeRef() throws TraceSpanTreeSerializeException { + if (prev != null) { + prevNodeRefToken = prev.getNodeRefToken(); + } + if (parent != null) { + parentNodeRefToken = parent.getNodeRefToken(); + } + if (next != null) { + nextNodeRefToken = next.getNodeRefToken(); + } + if (sub != null) { + subNodeRefToken = sub.getNodeRefToken(); + } + } } 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 0d0841381..9f0487586 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,145 +1,185 @@ package com.ai.cloud.skywalking.analysis.chainbuild.entity; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -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.TraceSpanTreeSerializeException; import com.ai.cloud.skywalking.analysis.chainbuild.util.StringUtil; import com.ai.cloud.skywalking.analysis.chainbuild.util.TokenGenerator; import com.ai.cloud.skywalking.protocol.Span; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import org.apache.hadoop.io.Writable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class TraceSpanTree { - private Logger logger = LoggerFactory.getLogger(TraceSpanTree.class); - - private String userId = null; - - private String cid; - - private TraceSpanNode treeRoot; - - private List spanContainer = new ArrayList(); - - public TraceSpanTree() { - } - - public String build(List spanList) throws BuildTraceSpanTreeException { - if (spanList.size() == 0) { - throw new BuildTraceSpanTreeException("spanList is empty."); - } - - 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)); - } - } - - return cid; - } - - private void build(Span span) throws BuildTraceSpanTreeException { - if (userId == null && span.getUserId() != null) { - userId = span.getUserId(); - } - - 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); - if (foundNode != null) { - new TraceSpanNode(null, null, foundNode, foundNode.next(), 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))); - - } - } - - private TraceSpanNode findNodeAndCreateVisualNodeIfNess( - String parentLevelId, int levelId) { - 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(); - } 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(); - } else { - // create visual sub node - currentNode = new VisualTraceSpanNode(currentNode, null, null, - null, contextParentLevelId, 0, spanContainer); - } - } - - return currentNode; - } - - 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"); - } - } - - - private void beforeSerialize() throws TraceSpanTreeSerializeException{ - for(TraceSpanNode treeNode : spanContainer){ - treeNode.serializeRef(); - } - } +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); + + private String userId = null; + + private String cid; + + private TraceSpanNode treeRoot; + + private List spanContainer = new ArrayList(); + + public TraceSpanTree() { + } + + public String build(List spanList) throws BuildTraceSpanTreeException { + if (spanList.size() == 0) { + throw new BuildTraceSpanTreeException("spanList is empty."); + } + + 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)); + } + } + + return cid; + } + + private void build(Span span) throws BuildTraceSpanTreeException { + if (userId == null && span.getUserId() != null) { + userId = span.getUserId(); + } + + 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); + if (foundNode != null) { + new TraceSpanNode(null, null, foundNode, foundNode.next(), 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))); + + } + } + + private TraceSpanNode findNodeAndCreateVisualNodeIfNess( + String parentLevelId, int levelId) { + 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(); + } 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(); + } else { + // create visual sub node + currentNode = new VisualTraceSpanNode(currentNode, null, null, + null, contextParentLevelId, 0, spanContainer); + } + } + + return currentNode; + } + + 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"); + } + } + + + private void beforeSerialize() throws TraceSpanTreeSerializeException { + for (TraceSpanNode treeNode : spanContainer) { + treeNode.serializeRef(); + } + } + + public String serialize() throws TraceSpanTreeSerializeException { + beforeSerialize(); + return new Gson().toJson(this); + } + + @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()); + } catch (Exception e) { + logger.error("Failed to parse the value[" + value + "] to TraceSpanTree Object", e); + } + } + + public TraceSpanNode getTreeRoot() { + return treeRoot; + } } -- GitLab