Authored by wangning

增加异常调用链分析

@@ -60,6 +60,8 @@ public class ApiStatisticsAnalyzer implements Serializable { @@ -60,6 +60,8 @@ public class ApiStatisticsAnalyzer implements Serializable {
60 result.setApiName(trace._2().getApi()); 60 result.setApiName(trace._2().getApi());
61 result.setCallTimes(1); 61 result.setCallTimes(1);
62 result.setTraceMd5(trace._1()); 62 result.setTraceMd5(trace._1());
  63 + result.setErrorStatus(trace._2().isErrorStatus());
  64 + result.setTraceId(trace._2().getTraceid());
63 65
64 List<SpanInfo> spanList = trace._2().getSortSpanList(); 66 List<SpanInfo> spanList = trace._2().getSortSpanList();
65 List<SpanResult> spanResultList = new ArrayList<SpanResult>(); 67 List<SpanResult> spanResultList = new ArrayList<SpanResult>();
@@ -67,7 +69,7 @@ public class ApiStatisticsAnalyzer implements Serializable { @@ -67,7 +69,7 @@ public class ApiStatisticsAnalyzer implements Serializable {
67 while (itor.hasNext()) { 69 while (itor.hasNext()) {
68 SpanInfo span = (SpanInfo) itor.next(); 70 SpanInfo span = (SpanInfo) itor.next();
69 SpanResult spanResult = new SpanResult(span.getName(), span.getEnd() - span.getBegin(), span.getLevel(), 71 SpanResult spanResult = new SpanResult(span.getName(), span.getEnd() - span.getBegin(), span.getLevel(),
70 - span.getSpanid(), span.getParent(), span.getSrcService(), span.getDstService(), null, null); 72 + span.getSpanid(), span.getParent(), span.getSrcService(), span.getDstService(), null, null,span.isErrorStatus());
71 spanResultList.add(spanResult); 73 spanResultList.add(spanResult);
72 } 74 }
73 75
@@ -77,6 +79,7 @@ public class ApiStatisticsAnalyzer implements Serializable { @@ -77,6 +79,7 @@ public class ApiStatisticsAnalyzer implements Serializable {
77 result.setMinLatencyTrace(trace._2().getTraceid()); 79 result.setMinLatencyTrace(trace._2().getTraceid());
78 result.setMaxLatency((int) trace._2().getDuration()); 80 result.setMaxLatency((int) trace._2().getDuration());
79 result.setMinLatency((int) trace._2().getDuration()); 81 result.setMinLatency((int) trace._2().getDuration());
  82 + result.setTraceStartTime(trace._2().getTraceStartTime());
80 83
81 return new Tuple2<String, ApiTraceResult>(trace._1(), result); 84 return new Tuple2<String, ApiTraceResult>(trace._1(), result);
82 } 85 }
@@ -173,8 +176,14 @@ public class ApiStatisticsAnalyzer implements Serializable { @@ -173,8 +176,14 @@ public class ApiStatisticsAnalyzer implements Serializable {
173 String api = rootSpan.getName() ; 176 String api = rootSpan.getName() ;
174 StringBuilder key = new StringBuilder() ; 177 StringBuilder key = new StringBuilder() ;
175 Iterator it = sortSpanList.iterator() ; 178 Iterator it = sortSpanList.iterator() ;
  179 + //判断该treace是否是异常调用链
  180 + boolean traceErrorStatus = false;
176 while(it.hasNext()) { 181 while(it.hasNext()) {
177 - key.append( ((SpanInfo)it.next()).getName()+"|"); 182 + SpanInfo si = (SpanInfo)it.next();
  183 + key.append(si.getName()+"|");
  184 + if(si.isErrorStatus()){
  185 + traceErrorStatus = true;
  186 + }
178 } 187 }
179 188
180 String keyMd5 = MD5.md5(key.toString()); 189 String keyMd5 = MD5.md5(key.toString());
@@ -184,7 +193,9 @@ public class ApiStatisticsAnalyzer implements Serializable { @@ -184,7 +193,9 @@ public class ApiStatisticsAnalyzer implements Serializable {
184 trace.setDuration(duration); 193 trace.setDuration(duration);
185 trace.setTraceid(rootSpan.getTraceid()); 194 trace.setTraceid(rootSpan.getTraceid());
186 trace.setSortSpanList(sortSpanList); 195 trace.setSortSpanList(sortSpanList);
187 - 196 + trace.setErrorStatus(traceErrorStatus);
  197 + //root开始时间当做trace的开始时间
  198 + trace.setTraceStartTime(rootSpan.getBegin());
188 199
189 //毫秒转换为 秒,丢失 毫秒数 200 //毫秒转换为 秒,丢失 毫秒数
190 long beginSec = rootSpan.getReceive()/1000 ; 201 long beginSec = rootSpan.getReceive()/1000 ;
@@ -29,4 +29,10 @@ public class ApiTraceResult implements Serializable { @@ -29,4 +29,10 @@ public class ApiTraceResult implements Serializable {
29 29
30 String prefex ; 30 String prefex ;
31 31
  32 + String traceId;
  33 +
  34 + boolean errorStatus;
  35 +
  36 + long traceStartTime;
  37 +
32 } 38 }
@@ -19,4 +19,7 @@ public class SortedTrace implements Serializable { @@ -19,4 +19,7 @@ public class SortedTrace implements Serializable {
19 long startMinute ; 19 long startMinute ;
20 long startDay ; 20 long startDay ;
21 21
  22 + boolean errorStatus;
  23 + long traceStartTime;
  24 +
22 } 25 }
@@ -33,4 +33,7 @@ public class SpanInfo implements Serializable { @@ -33,4 +33,7 @@ public class SpanInfo implements Serializable {
33 private String pageId; 33 private String pageId;
34 34
35 private String httpHost; 35 private String httpHost;
  36 +
  37 + private boolean errorStatus;
  38 + long duration;
36 } 39 }
@@ -23,9 +23,10 @@ public class SpanResult implements Serializable { @@ -23,9 +23,10 @@ public class SpanResult implements Serializable {
23 23
24 List<String> srcIp ; 24 List<String> srcIp ;
25 List<String> dstIp ; 25 List<String> dstIp ;
  26 + boolean errorStatus;
26 27
27 28
28 - public SpanResult(String spanName, long duration,int level,String spanId, String parent, String srcService, String dstService, List<String> srcIp, List<String> dstIp ){ 29 + public SpanResult(String spanName, long duration,int level,String spanId, String parent, String srcService, String dstService, List<String> srcIp, List<String> dstIp,boolean errorStatus ){
29 this.spanName = spanName ; 30 this.spanName = spanName ;
30 this.spanId = spanId ; 31 this.spanId = spanId ;
31 this.duration = duration ; 32 this.duration = duration ;
@@ -36,6 +37,7 @@ public class SpanResult implements Serializable { @@ -36,6 +37,7 @@ public class SpanResult implements Serializable {
36 this.dstService = dstService ; 37 this.dstService = dstService ;
37 this.srcIp = srcIp ; 38 this.srcIp = srcIp ;
38 this.dstIp = dstIp ; 39 this.dstIp = dstIp ;
  40 + this.errorStatus = errorStatus;
39 } 41 }
40 42
41 } 43 }
@@ -116,7 +116,7 @@ public class ApiAnalyzeHandler implements IAnalyzeHandler, Serializable { @@ -116,7 +116,7 @@ public class ApiAnalyzeHandler implements IAnalyzeHandler, Serializable {
116 List<SpanResult> list = new ArrayList(); 116 List<SpanResult> list = new ArrayList();
117 for (int i = 0; i < spanList.size(); i++) { 117 for (int i = 0; i < spanList.size(); i++) {
118 list.add(new SpanResult(spanList.get(i).getName(), durationPerStep.get(String.valueOf(spanList.get(i).getName())), 118 list.add(new SpanResult(spanList.get(i).getName(), durationPerStep.get(String.valueOf(spanList.get(i).getName())),
119 - spanList.get(i).getLevel(), spanList.get(i).getSpanid() ,spanList.get(i).getParent() , spanList.get(i).getSrcService(), spanList.get(i).getDstService(), null, null)); 119 + spanList.get(i).getLevel(), spanList.get(i).getSpanid() ,spanList.get(i).getParent() , spanList.get(i).getSrcService(), spanList.get(i).getDstService(), null, null,spanList.get(i).isErrorStatus()));
120 } 120 }
121 121
122 122
@@ -79,6 +79,7 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable { @@ -79,6 +79,7 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable {
79 spanInfo.setName(span.getName()); 79 spanInfo.setName(span.getName());
80 spanInfo.setBegin(span.getBegin()); 80 spanInfo.setBegin(span.getBegin());
81 spanInfo.setEnd(span.getEnd()); 81 spanInfo.setEnd(span.getEnd());
  82 + spanInfo.setDuration(span.getEnd() - span.getBegin());
82 spanInfo.setTraceid(Span.idToHex(span.getTraceId())); 83 spanInfo.setTraceid(Span.idToHex(span.getTraceId()));
83 spanInfo.setSpanid(Span.idToHex(span.getSpanId())); 84 spanInfo.setSpanid(Span.idToHex(span.getSpanId()));
84 if (span.getParents().size() > 0) { 85 if (span.getParents().size() > 0) {
@@ -90,7 +91,12 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable { @@ -90,7 +91,12 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable {
90 spanInfo.setReceive(spans.getReceive()); 91 spanInfo.setReceive(spans.getReceive());
91 if(span.tags()!=null){ 92 if(span.tags()!=null){
92 spanInfo.setHttpHost(span.tags().get("http.host")); 93 spanInfo.setHttpHost(span.tags().get("http.host"));
  94 + //标记span是否是是异常span
  95 + if(StringUtils.isNotBlank(span.tags().get("error"))){
  96 + spanInfo.setErrorStatus(true);
  97 + }
93 } 98 }
  99 +
94 spanInfoList.add(new Tuple2<>(spanInfo.getTraceid(), spanInfo)); 100 spanInfoList.add(new Tuple2<>(spanInfo.getTraceid(), spanInfo));
95 } 101 }
96 } 102 }
@@ -247,23 +253,17 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable { @@ -247,23 +253,17 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable {
247 253
248 sortSpanTrace.cache(); 254 sortSpanTrace.cache();
249 255
250 - //处理span+ip的耗时分布 256 + //1处理span+ip的耗时分布
251 handlerSpanIp(sortSpanTrace); 257 handlerSpanIp(sortSpanTrace);
252 258
253 JavaPairDStream<String, ApiTraceResult> apiResultTraceDStream = sortSpanTrace.mapToPair(analyzer.ConvertTraceResultFunc) ; 259 JavaPairDStream<String, ApiTraceResult> apiResultTraceDStream = sortSpanTrace.mapToPair(analyzer.ConvertTraceResultFunc) ;
  260 + apiResultTraceDStream.cache();
254 261
255 - //根据traceMD5分组计算value  
256 - JavaPairDStream<String, ApiTraceResult> resultDStream = apiResultTraceDStream.reduceByKey(analyzer.ReduceFunc) ;  
257 -  
258 - resultDStream.foreachRDD(new VoidFunction<JavaPairRDD<String, ApiTraceResult>>() {  
259 - @Override  
260 - public void call(JavaPairRDD<String, ApiTraceResult> apiResultRdd) throws Exception {  
261 -  
262 - ApiStatisticsResultStore.store(apiResultRdd, "trace_api_analyze_minutes");  
263 - }  
264 - });  
265 - 262 + //2处理treemd5调用链总览
  263 + handlertraceApiAnalyzeMinutes(apiResultTraceDStream);
266 264
  265 + //3处理异常调用链信息
  266 + handlerExceptionTrace(apiResultTraceDStream);
267 } 267 }
268 268
269 269
@@ -369,4 +369,78 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable { @@ -369,4 +369,78 @@ public class TraceAnalyzeHandler implements TraceHandler, Serializable {
369 }); 369 });
370 370
371 } 371 }
  372 +
  373 +
  374 +
  375 + private void handlertraceApiAnalyzeMinutes(JavaPairDStream<String, ApiTraceResult> apiResultTraceDStream){
  376 + //根据traceMD5分组计算value
  377 + JavaPairDStream<String, ApiTraceResult> resultDStream = apiResultTraceDStream.reduceByKey(analyzer.ReduceFunc) ;
  378 +
  379 + resultDStream.foreachRDD(new VoidFunction<JavaPairRDD<String, ApiTraceResult>>() {
  380 + @Override
  381 + public void call(JavaPairRDD<String, ApiTraceResult> apiResultRdd) throws Exception {
  382 +
  383 + ApiStatisticsResultStore.store(apiResultRdd, "trace_api_analyze_minutes");
  384 + }
  385 + });
  386 + }
  387 +
  388 + private void handlerExceptionTrace(JavaPairDStream<String, ApiTraceResult> apiResultTraceDStream){
  389 + JavaPairDStream<String, ApiTraceResult> filter = apiResultTraceDStream.filter(new Function<Tuple2<String, ApiTraceResult>, Boolean>() {
  390 + @Override
  391 + public Boolean call(Tuple2<String, ApiTraceResult> stringSortedTraceTuple2) throws Exception {
  392 + if(stringSortedTraceTuple2._2.isErrorStatus()){
  393 + return true;
  394 + }else{
  395 + return false;
  396 + }
  397 + }
  398 + });
  399 +
  400 +
  401 +
  402 +
  403 + filter.foreachRDD(new VoidFunction<JavaPairRDD<String, ApiTraceResult>>() {
  404 + @Override
  405 + public void call(JavaPairRDD<String, ApiTraceResult> stringSortedTraceJavaPairRDD) throws Exception {
  406 + stringSortedTraceJavaPairRDD.foreachPartition(new VoidFunction<Iterator<Tuple2<String, ApiTraceResult>>>() {
  407 + @Override
  408 + public void call(Iterator<Tuple2<String, ApiTraceResult>> tuple2Iterator) throws Exception {
  409 + HTable resultTable = null;
  410 + try {
  411 + if(tuple2Iterator == null){
  412 + return;
  413 + }
  414 +
  415 + if (resultTable == null) {
  416 + resultTable = (HTable) HBasePool.getConnection().getTable(TableName.valueOf("exception_trace"));
  417 + }
  418 +
  419 + List<Put> putList = new ArrayList<>();
  420 + while(tuple2Iterator.hasNext()){
  421 + Tuple2<String, ApiTraceResult> next = tuple2Iterator.next();
  422 + ApiTraceResult apiTraceResult = next._2;
  423 +
  424 + Put put = new Put(Bytes.toBytes(apiTraceResult.getTraceStartTime()/1000 + ":" + apiTraceResult.getTraceId()));
  425 + put.addColumn(Bytes.toBytes("data"), Bytes.toBytes("spans"), Bytes.toBytes(JSONObject.toJSONString(apiTraceResult.getSpans())));
  426 + put.addColumn(Bytes.toBytes("data"), Bytes.toBytes("traceid"), Bytes.toBytes(apiTraceResult.getTraceId()));
  427 + put.addColumn(Bytes.toBytes("data"), Bytes.toBytes("starttime"), Bytes.toBytes(apiTraceResult.getTraceStartTime()/1000));
  428 +
  429 + putList.add(put);
  430 + }
  431 +
  432 + resultTable.put(putList);
  433 +
  434 +
  435 + } catch (Exception e) {
  436 + logger.error(e.getMessage(),e);
  437 + } finally {
  438 + if (resultTable != null)
  439 + resultTable.close();
  440 + }
  441 + }
  442 + });
  443 + }
  444 + });
  445 + }
372 } 446 }