private void appendEventsToTraces(List<List<Span>> traces) throws IOException {
        final Map<String, List<Span>> traceIdWithSpans = traces.stream().filter(CollectionUtils::isNotEmpty)
            .collect(Collectors.toMap(s -> s.get(0).traceId(), Function.identity(), (s1, s2) -> s1));
        if (CollectionUtils.isEmpty(traceIdWithSpans)) {
            return;
        }

        final List<SpanAttachedEventRecord> records = getSpanAttachedEventQueryDAO().queryZKSpanAttachedEventsDebuggable(SpanAttachedEventTraceType.ZIPKIN,
            new ArrayList<>(traceIdWithSpans.keySet()), null);
        final Map<String, List<SpanAttachedEventRecord>> traceEvents = records.stream().collect(Collectors.groupingBy(SpanAttachedEventRecord::getRelatedTraceId));
        for (Map.Entry<String, List<SpanAttachedEventRecord>> entry : traceEvents.entrySet()) {
            appendEventsDebuggable(traceIdWithSpans.get(entry.getKey()), entry.getValue());
        }
    }
Reference from zipkin2.server.internal.ZipkinQueryApiV2 for the API consistent.
oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/handler/ZipkinQueryHandler.java