From 0664bcdcb4bbf9e37ed3d497ed28e527d40bd819 Mon Sep 17 00:00:00 2001 From: mrproliu <741550557@qq.com> Date: Thu, 30 Mar 2023 18:39:28 +0800 Subject: [PATCH] Fix trace profiling segments build failure when span list not ordering (#10613) --- .../trace/ProfileTaskQueryService.java | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java index efa9487ecb..df8065a07b 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/profiling/trace/ProfileTaskQueryService.java @@ -264,31 +264,43 @@ public class ProfileTaskQueryService implements Service { // trying to find parent final ArrayList results = new ArrayList<>(); final Iterator> entryIterator = segments.entrySet().iterator(); + final Set mergedSpans = new HashSet<>(); while (entryIterator.hasNext()) { // keep segment if no ref final Map.Entry current = entryIterator.next(); - if (CollectionUtils.isEmpty(current.getValue().getSpans().get(0).getRefs())) { - results.add(current.getValue()); - continue; - } - // keep segment if ref type is not same process(analyze only match with the same process) - final Ref ref = current.getValue().getSpans().get(0).getRefs().get(0); - if (RefType.CROSS_PROCESS.equals(ref.getType())) { - results.add(current.getValue()); - continue; + + boolean spanBeenAdded = false; + for (ProfiledSpan span : current.getValue().getSpans()) { + if (mergedSpans.contains(span)) { + continue; + } + if (CollectionUtils.isEmpty(span.getRefs())) { + continue; + } + // keep segment if ref type is not same process(analyze only match with the same process) + final Ref ref = span.getRefs().get(0); + if (RefType.CROSS_PROCESS.equals(ref.getType())) { + results.add(current.getValue()); + spanBeenAdded = true; + break; + } + // find parent segment if exist + final ProfiledTraceSegments parentSegments = segments.get(ref.getParentSegmentId()); + if (parentSegments != null) { + // append merged spans + mergedSpans.addAll(current.getValue().getSpans()); + // add current segments into parent + parentSegments.merge(current.getValue()); + // set parent segments(combined) as current segment + current.setValue(parentSegments); + spanBeenAdded = true; + break; + } } - // find parent segment if exist - final ProfiledTraceSegments parentSegments = segments.get(ref.getParentSegmentId()); - if (parentSegments == null) { + if (!spanBeenAdded) { results.add(current.getValue()); - continue; } - - // add current segments into parent - parentSegments.merge(current.getValue()); - // set parent segments(combined) as current segment - current.setValue(parentSegments); } return results.stream().filter(ProfiledTraceSegments::isContainsProfiled).peek(this::removeAllCrossProcessRef).collect(Collectors.toList());