1. 添加TraceSpanTree序列化方法
2. 将Mapper的Keyout对象修改成TraceSpanTree
This commit is contained in:
parent
06445fc592
commit
6f08371c5d
|
|
@ -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<Text, Text> {
|
||||
private Logger logger = LoggerFactory
|
||||
.getLogger(ChainBuildMapper.class);
|
||||
public class ChainBuildMapper extends TableMapper<Text, TraceSpanTree> {
|
||||
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<Span> spanList = new ArrayList<Span>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@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<Span> spanList = new ArrayList<Span>();
|
||||
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);
|
||||
context.write(new Text(tree.getTreeRoot().getNodeRefToken()), tree);
|
||||
} catch (Throwable e) {
|
||||
logger.error("Failed to mapper call chain[" + key.toString() + "]",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 TraceSpanNode prev = null;
|
||||
|
||||
protected int levelId;
|
||||
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 String viewPointId = "";
|
||||
|
||||
protected long cost = 0;
|
||||
|
||||
protected long callTimes = 0;
|
||||
|
||||
/**
|
||||
* 节点调用的状态<br/>
|
||||
* 0:成功<br/>
|
||||
* 1:异常<br/>
|
||||
* 异常判断原则:代码产生exception,并且此exception不在忽略列表中
|
||||
*/
|
||||
protected byte statusCode = 0;
|
||||
|
||||
protected byte statusCode = 0;
|
||||
|
||||
/**
|
||||
* 节点调用的错误堆栈<br/>
|
||||
* 堆栈以JAVA的exception为主要判断依据
|
||||
*/
|
||||
protected String exceptionStack;
|
||||
protected String exceptionStack;
|
||||
/**
|
||||
* 节点类型描述<br/>
|
||||
* 已字符串的形式描述<br/>
|
||||
* 如:java,dubbo等
|
||||
*/
|
||||
protected String spanType = "";
|
||||
|
||||
protected String spanType = "";
|
||||
|
||||
/**
|
||||
* 节点调用过程中的业务字段<br/>
|
||||
* 如:业务系统设置的订单号,SQL语句等
|
||||
*/
|
||||
protected String businessKey = "";
|
||||
|
||||
protected String businessKey = "";
|
||||
|
||||
/**
|
||||
* 节点调用所在的系统逻辑名称<br/>
|
||||
* 由授权文件指定
|
||||
*/
|
||||
protected String applicationId = "";
|
||||
|
||||
public TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, Span span, List<TraceSpanNode> 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<TraceSpanNode> 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<TraceSpanNode> 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;
|
||||
}
|
||||
protected String applicationId = "";
|
||||
|
||||
public TraceSpanNode next() {
|
||||
return next;
|
||||
}
|
||||
public TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, Span span, List<TraceSpanNode> 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();
|
||||
|
||||
public TraceSpanNode parent() {
|
||||
return parent;
|
||||
}
|
||||
//nodeToken : MD5(parentLevelId + levelId + viewpoint)
|
||||
nodeRefToken = TokenGenerator.generateNodeToken(parentLevel + "-" + levelId + "-" + viewPointId);
|
||||
|
||||
public TraceSpanNode sub() {
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrev(TraceSpanNode prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, List<TraceSpanNode> 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);
|
||||
}
|
||||
|
||||
public void setNext(TraceSpanNode next) {
|
||||
this.next = next;
|
||||
}
|
||||
protected TraceSpanNode(TraceSpanNode parent, TraceSpanNode sub, TraceSpanNode prev, TraceSpanNode next, String parentLevelId, int levelId, List<TraceSpanNode> spanContainer) {
|
||||
this(parent, sub, prev, next, spanContainer);
|
||||
this.parentLevel = parentLevelId;
|
||||
this.levelId = levelId;
|
||||
this.callTimes = 0;
|
||||
}
|
||||
|
||||
public void setParent(TraceSpanNode parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
boolean hasNext() {
|
||||
if (this.next != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSub(TraceSpanNode sub) {
|
||||
this.sub = sub;
|
||||
}
|
||||
boolean hasSub() {
|
||||
if (this.sub != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisualNode() {
|
||||
return visualNode;
|
||||
}
|
||||
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 String getParentLevel() {
|
||||
return parentLevel;
|
||||
}
|
||||
public TraceSpanNode prev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public int getLevelId() {
|
||||
return levelId;
|
||||
}
|
||||
public TraceSpanNode next() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public String getViewPointId() {
|
||||
return viewPointId;
|
||||
}
|
||||
public TraceSpanNode parent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public long getCost() {
|
||||
return cost;
|
||||
}
|
||||
public TraceSpanNode sub() {
|
||||
return sub;
|
||||
}
|
||||
|
||||
public byte getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
public void setPrev(TraceSpanNode prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
public String getExceptionStack() {
|
||||
return exceptionStack;
|
||||
}
|
||||
public void setNext(TraceSpanNode next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public String getSpanType() {
|
||||
return spanType;
|
||||
}
|
||||
public void setParent(TraceSpanNode parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getBusinessKey() {
|
||||
return businessKey;
|
||||
}
|
||||
public void setSub(TraceSpanNode sub) {
|
||||
this.sub = sub;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
public boolean isVisualNode() {
|
||||
return visualNode;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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;
|
||||
|
||||
private String userId = null;
|
||||
public class TraceSpanTree implements Writable {
|
||||
private Logger logger = LoggerFactory.getLogger(TraceSpanTree.class);
|
||||
|
||||
private String cid;
|
||||
private String userId = null;
|
||||
|
||||
private TraceSpanNode treeRoot;
|
||||
|
||||
private List<TraceSpanNode> spanContainer = new ArrayList<TraceSpanNode>();
|
||||
private String cid;
|
||||
|
||||
public TraceSpanTree() {
|
||||
}
|
||||
private TraceSpanNode treeRoot;
|
||||
|
||||
public String build(List<Span> spanList) throws BuildTraceSpanTreeException {
|
||||
if (spanList.size() == 0) {
|
||||
throw new BuildTraceSpanTreeException("spanList is empty.");
|
||||
}
|
||||
private List<TraceSpanNode> spanContainer = new ArrayList<TraceSpanNode>();
|
||||
|
||||
Collections.sort(spanList, new Comparator<Span>() {
|
||||
@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 TraceSpanTree() {
|
||||
}
|
||||
|
||||
return cid;
|
||||
}
|
||||
public String build(List<Span> spanList) throws BuildTraceSpanTreeException {
|
||||
if (spanList.size() == 0) {
|
||||
throw new BuildTraceSpanTreeException("spanList is empty.");
|
||||
}
|
||||
|
||||
private void build(Span span) throws BuildTraceSpanTreeException {
|
||||
if (userId == null && span.getUserId() != null) {
|
||||
userId = span.getUserId();
|
||||
}
|
||||
Collections.sort(spanList, new Comparator<Span>() {
|
||||
@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));
|
||||
}
|
||||
}
|
||||
|
||||
TraceSpanNode clientOrServerNode = findNodeAndCreateVisualNodeIfNess(
|
||||
span.getParentLevel(), span.getLevelId());
|
||||
if (clientOrServerNode != null) {
|
||||
clientOrServerNode.mergeSpan(span);
|
||||
}
|
||||
return cid;
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
private TraceSpanNode findNodeAndCreateVisualNodeIfNess(
|
||||
String parentLevelId, int levelId) {
|
||||
String levelDesc = StringUtil.isBlank(parentLevelId) ? (levelId + "")
|
||||
: (parentLevelId + "." + levelId);
|
||||
String[] levelArray = levelDesc.split("\\.");
|
||||
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)));
|
||||
|
||||
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 TraceSpanNode findNodeAndCreateVisualNodeIfNess(
|
||||
String parentLevelId, int levelId) {
|
||||
String levelDesc = StringUtil.isBlank(parentLevelId) ? (levelId + "")
|
||||
: (parentLevelId + "." + levelId);
|
||||
String[] levelArray = levelDesc.split("\\.");
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
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<List<TraceSpanNode>>() {
|
||||
}.getType());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to parse the value[" + value + "] to TraceSpanTree Object", e);
|
||||
}
|
||||
}
|
||||
|
||||
public TraceSpanNode getTreeRoot() {
|
||||
return treeRoot;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue