This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch camel-4.14.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit 161c1fa363c7df3abef9fc287ad7b1c47d8cf715 Author: Pasquale Congiusti <[email protected]> AuthorDate: Fri Aug 29 12:37:47 2025 +0200 fix(components): telemetry-dev async Closes CAMEL-22388 --- .../apache/camel/telemetrydev/DevSpanAdapter.java | 10 ++- .../org/apache/camel/telemetrydev/DevTrace.java | 72 +++++++++++++++++++++- .../apache/camel/telemetrydev/DevTraceFormat.java | 17 ++--- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevSpanAdapter.java b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevSpanAdapter.java index 3f5f6fe84e3..8f37cf8a035 100644 --- a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevSpanAdapter.java +++ b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevSpanAdapter.java @@ -105,9 +105,17 @@ public class DevSpanAdapter implements Span { } } + public String getSpanId() { + return this.tags.get("spanid"); + } + + public String getParentSpanId() { + return this.tags.get("parentSpan"); + } + @Override public String toString() { - String toString = this.tags.get("traceid") + "-" + this.tags.get("spanid") + "-["; + String toString = this.tags.get("traceid") + "-" + getSpanId() + "-["; for (Entry<String, String> entry : this.tags().entrySet()) { if (!entry.getKey().equals("traceid") && !entry.getKey().equals("spanid")) { toString += entry.getKey() + "=" + entry.getValue() + ","; diff --git a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTrace.java b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTrace.java index 5d97053266b..b951f90359c 100644 --- a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTrace.java +++ b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTrace.java @@ -16,10 +16,14 @@ */ package org.apache.camel.telemetrydev; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Stack; -public class DevTrace { +public class DevTrace implements Iterable<DevSpanAdapter> { private String traceId; private List<DevSpanAdapter> spans; @@ -51,9 +55,75 @@ public class DevTrace { return this.spans; } + public List<DevSpanAdapter> sortSpans() { + List<DevSpanAdapter> spans = new ArrayList<>(); + for (DevSpanAdapter span : this) { + spans.add(span); + } + return spans; + } + void setSpans(List<DevSpanAdapter> spans) { this.spans = spans; } + + @Override + public Iterator<DevSpanAdapter> iterator() { + return new DevSpanAdapterIterator(); + } + + class DevSpanAdapterIterator implements Iterator<DevSpanAdapter> { + + Stack<DevSpanAdapter> actual = new Stack<>(); + private HashMap<String, Boolean> scanned; + + DevSpanAdapterIterator() { + this.scanned = new HashMap<>(); + this.actual = new Stack<>(); + } + + @Override + public boolean hasNext() { + return scanned.size() < spans.size(); + } + + @Override + public DevSpanAdapter next() { + DevSpanAdapter next; + if (actual.empty()) { + next = getWithParent(null); + } else { + next = getWithParent(actual.peek().getSpanId()); + } + while (next == null && !actual.empty()) { + // it's a leaf, let's find out the upper branch + DevSpanAdapter upperLevel = actual.pop(); + next = getWithParent(upperLevel.getParentSpanId()); + } + + actual.push(next); + scanned.put(next.getSpanId(), true); + return next; + } + + private DevSpanAdapter getWithParent(String parentSpanId) { + for (DevSpanAdapter span : spans) { + if (parentSpanId == null && + span.getParentSpanId() == null && + !scanned.containsKey(span.getSpanId())) { + return span; + } + if (span.getParentSpanId() != null && + span.getParentSpanId().equals(parentSpanId) && + !scanned.containsKey(span.getSpanId())) { + return span; + } + } + + return null; + } + + } } class SpanComparator implements java.util.Comparator<DevSpanAdapter> { diff --git a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTraceFormat.java b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTraceFormat.java index d1dc272a385..c53efc64957 100644 --- a/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTraceFormat.java +++ b/components/camel-telemetry-dev/src/main/java/org/apache/camel/telemetrydev/DevTraceFormat.java @@ -18,6 +18,7 @@ package org.apache.camel.telemetrydev; import java.io.StringWriter; import java.util.HashMap; +import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -79,10 +80,11 @@ class DevTraceFormatTree implements DevTraceFormat { sw.append("\n| " + trace.getTraceId() + "\n"); HashMap<String, Integer> depths = new HashMap<>(); int depth = 0; - for (int j = 0; j < trace.getSpans().size(); j++) { - DevSpanAdapter span = trace.getSpans().get(j); - String marker = getMarker(depths, span, j + 1 < trace.getSpans().size() ? trace.getSpans().get(j + 1) : null); - String actualParentSpan = span.getTag("parentSpan"); + List<DevSpanAdapter> spans = trace.sortSpans(); + for (int j = 0; j < spans.size(); j++) { + DevSpanAdapter span = spans.get(j); + String marker = getMarker(depths, span, j + 1 < spans.size() ? spans.get(j + 1) : null); + String actualParentSpan = span.getParentSpanId(); if (depths.containsKey(actualParentSpan)) { depth = depths.get(actualParentSpan); } else if (actualParentSpan != null) { @@ -131,9 +133,10 @@ class DevTraceFormatTree implements DevTraceFormat { String component = span.getTag("component"); String camelUri = span.getTag("camel.uri"); return String.format( - "| %s (%s) [%d millis] %s", + "| %s (%s) [%s] [%d millis] %s", camelUri == null ? "process" : camelUri, component, + span.getSpanId(), nanos, sentOrReceived); } @@ -142,8 +145,8 @@ class DevTraceFormatTree implements DevTraceFormat { if (next == null) { return "└"; } - Integer thisDepth = depths.get(span.getTag("parentSpan")); - Integer nextDepth = depths.get(next.getTag("parentSpan")); + Integer thisDepth = depths.get(span.getParentSpanId()); + Integer nextDepth = depths.get(next.getParentSpanId()); if (thisDepth == null && nextDepth == null) { return "├"; }
