Showing
7 changed files
with
116 additions
and
17 deletions
@@ -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 ; |
@@ -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 | } |
-
Please register or login to post a comment