/** * Loads all the data which is required for building the tree. */ private void prepare() { if (mode == Mode.SINGLE) { invocationSequences = Arrays.asList(invocationSequence); // loading all spans related to the set invocation sequence if (spanService != null) { Stream<InvocationSequenceData> invocationStream = InvocationSequenceDataHelper.asStream(invocationSequence); spans = invocationStream.map(i -> i.getSpanIdent()).filter(Objects::nonNull).map(spanService::get).filter(Objects::nonNull).collect(Collectors.toList()); } else { spans = new ArrayList<>(); } } else { if (traceId == null) { throw new IllegalStateException("A trace id have to be specified when a span tree has to be build and the mode is not set to SINGLE."); } spans = loadSpans(); if (mode == Mode.ALL) { invocationSequences = loadInvocationSequences(); } } if (mode != Mode.ONLY_SPANS_WITH_SDK) { spans.removeIf(s -> (s.getPropagationType() == null) && !s.isRoot()); } }
/** * Resolve the span details (like has nested exceptions, has SQL statement..). */ private void resolveSpanDetails() { // Load invocation sequences for calculating span details. We are doing this here again, // because we did not loaded any invocations at the beginning because we don't needed them // to build the tree. if (mode == Mode.ONLY_SPANS_WITH_SDK) { invocationSequences = loadInvocationSequences(); } // Creating a mapping from span ids to invocation sequences in order to prevent a continuous // iteration over the invocation sequences - when two spans refers the same // trace, we are trying to return the invocation sequence which follows the span (= is a // root span). Map<Long, InvocationSequenceData> spanToInvocationSequenceMap = InvocationSequenceDataHelper.asStream(invocationSequences).filter(InvocationSequenceDataHelper::hasSpanIdent) .collect(Collectors.toMap(i -> i.getSpanIdent().getId(), Function.identity(), (i1, i2) -> InvocationSequenceDataHelper.isRootElementInSequence(i1) ? i1 : i2)); // now we actually resolves the span details (like has nested exceptions..) tree.asStream().filter(e -> e.getType() == TreeElementType.SPAN).forEach(e -> resolveSpanDetails(e, spanToInvocationSequenceMap)); }