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 f339ade838 Support log context IN filters
f339ade838 is described below
commit f339ade83872f2faed485ebee551ed6c17e926c3
Author: Logic <[email protected]>
AuthorDate: Tue Jun 9 21:00:15 2026 +0800
Support log context IN filters
---
.../logs/service/impl/LogQueryServiceImpl.java | 11 +++-
.../logs/controller/LogQueryControllerTest.java | 67 ++++++++++++++++++++++
2 files changed, 75 insertions(+), 3 deletions(-)
diff --git
a/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/logs/service/impl/LogQueryServiceImpl.java
b/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/logs/service/impl/LogQueryServiceImpl.java
index 315782d62d..e17cb3c2fa 100644
---
a/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/logs/service/impl/LogQueryServiceImpl.java
+++
b/hertzbeat-observability/src/main/java/org/apache/hertzbeat/observability/logs/service/impl/LogQueryServiceImpl.java
@@ -452,7 +452,7 @@ public class LogQueryServiceImpl implements LogQueryService
{
Integer limit, String direction, Long
cursorLogTimeUnixNano,
boolean hideInternal, boolean
hideNoise) {
return contextWithFilters(logTimeUnixNano, start, end, serviceName,
serviceNamespace, environment,
- parseLogAttributeFilter(resourceFilter),
parseLogAttributeFilter(attributeFilter), limit, direction,
+ parseLogAttributeFilter(resourceFilter, true),
parseLogAttributeFilter(attributeFilter, true), limit, direction,
cursorLogTimeUnixNano, hideInternal, hideNoise);
}
@@ -464,9 +464,9 @@ public class LogQueryServiceImpl implements LogQueryService
{
boolean hideInternal, boolean
hideNoise) {
LogServiceContext context =
resolveEntityFirstLogServiceContext(entityId, serviceName, serviceNamespace,
environment);
Map<String, String> resourceFilters = removeEntityScopeResourceFilters(
- context, parseLogAttributeFilter(resourceFilter));
+ context, parseLogAttributeFilter(resourceFilter, true));
return contextWithFilters(logTimeUnixNano, start, end,
context.serviceName(), context.serviceNamespace(),
- context.environment(), resourceFilters,
parseLogAttributeFilter(attributeFilter), limit, direction,
+ context.environment(), resourceFilters,
parseLogAttributeFilter(attributeFilter, true), limit, direction,
cursorLogTimeUnixNano, hideInternal, hideNoise);
}
@@ -763,6 +763,11 @@ public class LogQueryServiceImpl implements
LogQueryService {
Map<String, String>
attributeFilters,
boolean hideInternal, boolean
hideNoise) {
boolean hasAttributeFilters = hasAttributeFilters(resourceFilters,
attributeFilters);
+ if (hasComplexAttributeFilters(resourceFilters, attributeFilters)) {
+ return getRowFilteredLogs(start, end, traceId, spanId,
severityNumber, severityText, search,
+ serviceName, serviceNamespace, environment,
resourceFilters, attributeFilters,
+ hideInternal, hideNoise);
+ }
for (HistoryDataReader historyDataReader : historyDataReaders) {
try {
List<LogEntry> logs;
diff --git
a/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/logs/controller/LogQueryControllerTest.java
b/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/logs/controller/LogQueryControllerTest.java
index 8cf11ff05e..b346ed91df 100644
---
a/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/logs/controller/LogQueryControllerTest.java
+++
b/hertzbeat-observability/src/test/java/org/apache/hertzbeat/observability/logs/controller/LogQueryControllerTest.java
@@ -856,6 +856,73 @@ class LogQueryControllerTest {
.andExpect(jsonPath("$.data.hasMoreAfter").value(true));
}
+ @Test
+ void testContextLogsAppliesInAndNotInFiltersWithRowFallback() throws
Exception {
+ long selectedTime = 1734005477630000000L;
+ LogEntry selectedLog = LogEntry.builder()
+ .timeUnixNano(selectedTime)
+ .severityText("ERROR")
+ .body("stable checkout selected")
+ .resource(new HashMap<>(java.util.Map.of(
+ "service.name", "checkout",
+ "service.version", "1.2.3",
+ "host.name", "checkout-1")))
+ .attributes(new HashMap<>(java.util.Map.of("http.route",
"/checkout")))
+ .build();
+ LogEntry beforeLog = LogEntry.builder()
+ .timeUnixNano(selectedTime - 1_000_000L)
+ .severityText("INFO")
+ .body("stable checkout before")
+ .resource(new HashMap<>(java.util.Map.of(
+ "service.name", "checkout",
+ "service.version", "1.2.4",
+ "host.name", "checkout-2")))
+ .attributes(new HashMap<>(java.util.Map.of("http.route",
"/checkout")))
+ .build();
+ LogEntry canaryLog = LogEntry.builder()
+ .timeUnixNano(selectedTime + 1_000_000L)
+ .severityText("INFO")
+ .body("canary checkout after")
+ .resource(new HashMap<>(java.util.Map.of(
+ "service.name", "checkout",
+ "service.version", "1.2.3",
+ "host.name", "checkout-canary")))
+ .attributes(new HashMap<>(java.util.Map.of("http.route",
"/checkout")))
+ .build();
+ LogEntry cartLog = LogEntry.builder()
+ .timeUnixNano(selectedTime + 2_000_000L)
+ .severityText("INFO")
+ .body("cart checkout after")
+ .resource(new HashMap<>(java.util.Map.of(
+ "service.name", "checkout",
+ "service.version", "1.2.4",
+ "host.name", "checkout-3")))
+ .attributes(new HashMap<>(java.util.Map.of("http.route",
"/cart")))
+ .build();
+ when(historyDataReader.queryLogsByMultipleConditions(any(), any(),
any(),
+ any(), any(), any(), any())).thenReturn(List.of(cartLog,
canaryLog, selectedLog, beforeLog));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/api/logs/context")
+ .param("logTimeUnixNano", String.valueOf(selectedTime))
+ .param("resourceFilter", "service.version IN ('1.2.3',
'1.2.4') "
+ + "and host.name NOT IN ('checkout-canary')")
+ .param("attributeFilter", "http.route IN
('/checkout')")
+ .param("limit", "1"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.code").value((int)
CommonConstants.SUCCESS_CODE))
+ .andExpect(jsonPath("$.data.before.length()").value(1))
+ .andExpect(jsonPath("$.data.before[0].body").value("stable
checkout before"))
+ .andExpect(jsonPath("$.data.selected.body").value("stable
checkout selected"))
+ .andExpect(jsonPath("$.data.after.length()").value(0));
+
+ verify(historyDataReader).queryLogsByMultipleConditions(any(), any(),
any(),
+ any(), any(), any(), any());
+ verify(historyDataReader,
never()).queryLogsByMultipleConditions(any(), any(), any(), any(), any(),
any(), any(),
+ anySet(), eq(false), any(), any(), any(), any(),
+ org.mockito.ArgumentMatchers.<Map<String, String>>any(),
+ org.mockito.ArgumentMatchers.<Map<String, String>>any());
+ }
+
@Test
void testContextLogsReturnsDirectionalRowsAfterCursor() throws Exception {
long selectedTime = 1734005477630000000L;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]