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 0e82832c46 Guard signal runtime dimensions from entity identity
0e82832c46 is described below

commit 0e82832c46a91b284154e599b08fca90253b54bd
Author: Logic <[email protected]>
AuthorDate: Mon Jun 8 09:45:13 2026 +0800

    Guard signal runtime dimensions from entity identity
---
 .../model/EntityCanonicalIdentityRegistry.java     | 26 +++++++++++++++++
 .../model/EntityCanonicalIdentityRegistryTest.java | 15 ++++++++++
 .../entity/EntityIdentityResolutionService.java    |  3 ++
 .../EntityIdentityResolutionServiceTest.java       | 34 ++++++++++++++++++++++
 4 files changed, 78 insertions(+)

diff --git 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistry.java
 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistry.java
index 1dc053f5db..dbf1d67b3a 100644
--- 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistry.java
+++ 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistry.java
@@ -47,6 +47,25 @@ public final class EntityCanonicalIdentityRegistry {
             "cloud.resource_id"
     );
 
+    public static final List<String> RUNTIME_SIGNAL_DIMENSION_KEYS = List.of(
+            "trace.id",
+            "trace_id",
+            "span.id",
+            "span_id",
+            "span.name",
+            "span_name",
+            "root_span_name",
+            "operation",
+            "operation.name",
+            "http.route",
+            "http.target",
+            "http.url",
+            "exception.type",
+            "exception.message",
+            "log.severity",
+            "severity.text"
+    );
+
     private static final Map<String, Integer> CANONICAL_PRIORITY = 
Map.ofEntries(
             Map.entry("service.instance.id", 140),
             Map.entry("host.id", 140),
@@ -71,7 +90,14 @@ public final class EntityCanonicalIdentityRegistry {
         return identityKey != null && 
CANONICAL_PRIORITY.containsKey(identityKey);
     }
 
+    public static boolean isRuntimeSignalDimensionKey(String identityKey) {
+        return identityKey != null && 
RUNTIME_SIGNAL_DIMENSION_KEYS.contains(identityKey);
+    }
+
     public static int defaultPriority(String identityKey) {
+        if (isRuntimeSignalDimensionKey(identityKey)) {
+            return 0;
+        }
         return CANONICAL_PRIORITY.getOrDefault(identityKey, 40);
     }
 }
diff --git 
a/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistryTest.java
 
b/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistryTest.java
index e3ecd27038..c2e4f396bf 100644
--- 
a/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistryTest.java
+++ 
b/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/observability/model/EntityCanonicalIdentityRegistryTest.java
@@ -33,4 +33,19 @@ class EntityCanonicalIdentityRegistryTest {
         assertEquals(140, 
EntityCanonicalIdentityRegistry.defaultPriority("service.instance.id"));
         assertEquals(40, 
EntityCanonicalIdentityRegistry.defaultPriority("custom.key"));
     }
+
+    @Test
+    void shouldKeepRuntimeSignalDimensionsOutOfStableEntityIdentities() {
+        
assertTrue(EntityCanonicalIdentityRegistry.isRuntimeSignalDimensionKey("trace_id"));
+        
assertTrue(EntityCanonicalIdentityRegistry.isRuntimeSignalDimensionKey("span.name"));
+        
assertTrue(EntityCanonicalIdentityRegistry.isRuntimeSignalDimensionKey("http.route"));
+        
assertTrue(EntityCanonicalIdentityRegistry.isRuntimeSignalDimensionKey("exception.type"));
+
+        
assertFalse(EntityCanonicalIdentityRegistry.isCanonicalOtelResourceKey("trace_id"));
+        
assertFalse(EntityCanonicalIdentityRegistry.isCanonicalOtelResourceKey("span.name"));
+        
assertFalse(EntityCanonicalIdentityRegistry.isCanonicalOtelResourceKey("http.route"));
+        
assertFalse(EntityCanonicalIdentityRegistry.isCanonicalOtelResourceKey("exception.type"));
+        assertEquals(0, 
EntityCanonicalIdentityRegistry.defaultPriority("trace_id"));
+        assertEquals(0, 
EntityCanonicalIdentityRegistry.defaultPriority("http.route"));
+    }
 }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionService.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionService.java
index e85378fcf1..5e1c742b2d 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionService.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionService.java
@@ -148,6 +148,9 @@ public class EntityIdentityResolutionService {
     }
 
     public int defaultIdentityPriority(String identityKey) {
+        if 
(EntityCanonicalIdentityRegistry.isRuntimeSignalDimensionKey(identityKey)) {
+            return 0;
+        }
         if 
(EntityCanonicalIdentityRegistry.isCanonicalOtelResourceKey(identityKey)) {
             return 
EntityCanonicalIdentityRegistry.defaultPriority(identityKey);
         }
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionServiceTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionServiceTest.java
index e289c4c865..3d5bfdc745 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionServiceTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/entity/EntityIdentityResolutionServiceTest.java
@@ -36,6 +36,7 @@ import 
org.apache.hertzbeat.common.entity.manager.ObserveEntity;
 import org.apache.hertzbeat.manager.pojo.dto.EntityMonitorBindingCandidate;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
@@ -178,4 +179,37 @@ class EntityIdentityResolutionServiceTest {
         
verify(entityWorkspaceAccessService).findAccessibleEntitiesByIdsForRequestWorkspace(Set.of(301L,
 302L));
         verify(entityWorkspaceAccessService, 
never()).currentRequestWorkspaceId();
     }
+
+    @Test
+    void 
resolveMonitorBindingCandidatesKeepsRuntimeSignalDimensionsOutOfIdentityLookup()
 {
+        Monitor monitor = Monitor.builder()
+                .id(503L)
+                .app("springboot3")
+                .name("checkout-api")
+                .labels(Map.of(
+                        "service.name", "checkout-api",
+                        "http.route", "/checkout",
+                        "trace_id", "6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b",
+                        "span.name", "POST /checkout"
+                ))
+                .build();
+        when(entityIdentityReadModelService.findMatchingIdentities(anySet(), 
anySet()))
+                .thenReturn(List.of());
+
+        List<EntityMonitorBindingCandidate> candidates =
+                
identityResolutionService.resolveMonitorBindingCandidates(monitor);
+
+        assertTrue(candidates.isEmpty());
+        ArgumentCaptor<Set<String>> identityKeysCaptor = 
ArgumentCaptor.forClass(Set.class);
+        
verify(entityIdentityReadModelService).findMatchingIdentities(identityKeysCaptor.capture(),
 anySet());
+        Set<String> identityKeys = identityKeysCaptor.getValue();
+        assertTrue(identityKeys.contains("service.name"));
+        assertTrue(identityKeys.contains("monitor.name"));
+        assertTrue(identityKeys.contains("monitor.app"));
+        assertTrue(identityKeys.stream().noneMatch("http.route"::equals));
+        assertTrue(identityKeys.stream().noneMatch("trace_id"::equals));
+        assertTrue(identityKeys.stream().noneMatch("span.name"::equals));
+        assertEquals(0, 
identityResolutionService.defaultIdentityPriority("http.route"));
+        assertEquals(0, 
identityResolutionService.defaultIdentityPriority("trace_id"));
+    }
 }


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

Reply via email to