This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch 2.0.0
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/2.0.0 by this push:
     new 8894b951df Support span name trace attribute filters
8894b951df is described below

commit 8894b951dfe31dcfb7385373b0f2bbe715ba4d8c
Author: Logic <[email protected]>
AuthorDate: Wed Jun 10 09:37:16 2026 +0800

    Support span name trace attribute filters
---
 .../service/impl/EntityTraceQueryServiceImpl.java  | 19 ++++++++++++++-
 .../impl/EntityTraceQueryServiceImplTest.java      | 28 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git 
a/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImpl.java
 
b/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImpl.java
index d164ff0136..b05a42fb9f 100644
--- 
a/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImpl.java
+++ 
b/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImpl.java
@@ -1206,7 +1206,24 @@ public class EntityTraceQueryServiceImpl implements 
EntityTraceQueryService {
             return false;
         }
         return trace.spans.stream()
-                .anyMatch(span -> matchesFilterMap(span.getSpanAttributes(), 
attributeFilters));
+                .anyMatch(span -> 
matchesFilterMap(spanAttributeFilterValues(span), attributeFilters));
+    }
+
+    private Map<String, String> spanAttributeFilterValues(TraceSpanNodeDto 
span) {
+        if (span == null) {
+            return Collections.emptyMap();
+        }
+        Map<String, String> values = new LinkedHashMap<>();
+        if (!CollectionUtils.isEmpty(span.getSpanAttributes())) {
+            values.putAll(span.getSpanAttributes());
+        }
+        String spanName = trimText(span.getSpanName());
+        if (spanName != null) {
+            values.putIfAbsent("span.name", spanName);
+            values.putIfAbsent("span_name", spanName);
+            values.putIfAbsent("spanName", spanName);
+        }
+        return values;
     }
 
     private boolean matchesFilterMap(Map<String, String> values, 
ResourceFilterSet filters) {
diff --git 
a/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImplTest.java
 
b/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImplTest.java
index f561c4d8fd..5bc8e48704 100644
--- 
a/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImplTest.java
+++ 
b/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/traces/service/impl/EntityTraceQueryServiceImplTest.java
@@ -848,6 +848,34 @@ class EntityTraceQueryServiceImplTest {
                 org.mockito.ArgumentMatchers.anyInt());
     }
 
+    @Test
+    void queryTraceListMatchesSyntheticSpanNameAttributeFilters() {
+        long now = System.currentTimeMillis();
+        long start = now - 120_000;
+        long end = now;
+        when(traceQueryRepository.queryRecentTraceRows(
+                eq(1500), eq(start), eq(end), eq("checkout-service"), 
org.mockito.ArgumentMatchers.isNull(),
+                org.mockito.ArgumentMatchers.isNull(), 
org.mockito.ArgumentMatchers.isNull(),
+                org.mockito.ArgumentMatchers.isNull(), 
org.mockito.ArgumentMatchers.isNull(),
+                org.mockito.ArgumentMatchers.isNull(), 
org.mockito.ArgumentMatchers.<Map<String, Set<String>>>any(),
+                eq(false))).thenReturn(List.of(
+                traceRow("trace-checkout", "span-root-1", null, "POST 
/checkout",
+                        "checkout-service", "STATUS_CODE_OK", now - 10_000, 
2_000_000L,
+                        Map.of("service.name", "checkout-service")),
+                traceRow("trace-inventory", "span-root-2", null, "GET 
/inventory",
+                        "checkout-service", "STATUS_CODE_OK", now - 9_000, 
2_000_000L,
+                        Map.of("service.name", "checkout-service"))
+        ));
+
+        var page = entityTraceQueryService.queryTraceList(null, start, end, 
null,
+                false, "checkout-service", null, null,
+                null, null, null, null, 0, 20, false, null,
+                "span.name=\"POST /checkout\"");
+
+        assertEquals(1, page.getTotalElements());
+        assertEquals("trace-checkout", 
page.getContent().getFirst().getTraceId());
+    }
+
     @Test
     void traceQueriesPreferEntityIdentityOverConflictingRouteContext() {
         long now = System.currentTimeMillis();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to