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 "├";
         }

Reply via email to