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]