feat(logs): add instanceIds multi-value filter to /logs endpoint
Adds List<String> instanceIds to LogSearchRequest (null-normalized to List.of() in compact ctor) and generates an IN clause in both ClickHouseLogStore.search() and countLogs(), mirroring the existing sources pattern. LogQueryController parses ?instanceIds= as a comma-split list. All existing LogSearchRequest call sites updated. New ClickHouseLogStoreInstanceIdsIT covers: multi-value filter, empty filter (all rows), null filter (all rows), single-value filter, and coexistence with the singular instanceId field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,7 +61,8 @@ public class LogPatternEvaluator implements ConditionEvaluator<LogPatternConditi
|
||||
to,
|
||||
null, // cursor
|
||||
1, // limit (count query; value irrelevant)
|
||||
"desc" // sort
|
||||
"desc", // sort
|
||||
null // instanceIds
|
||||
);
|
||||
return logStore.countLogs(req);
|
||||
});
|
||||
|
||||
@@ -44,6 +44,7 @@ public class LogQueryController {
|
||||
@RequestParam(required = false) String exchangeId,
|
||||
@RequestParam(required = false) String logger,
|
||||
@RequestParam(required = false) String source,
|
||||
@RequestParam(required = false) String instanceIds,
|
||||
@RequestParam(required = false) String from,
|
||||
@RequestParam(required = false) String to,
|
||||
@RequestParam(required = false) String cursor,
|
||||
@@ -69,12 +70,21 @@ public class LogQueryController {
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<String> instanceIdList = List.of();
|
||||
if (instanceIds != null && !instanceIds.isEmpty()) {
|
||||
instanceIdList = Arrays.stream(instanceIds.split(","))
|
||||
.map(String::trim)
|
||||
.filter(s -> !s.isEmpty())
|
||||
.toList();
|
||||
}
|
||||
|
||||
Instant fromInstant = from != null ? Instant.parse(from) : null;
|
||||
Instant toInstant = to != null ? Instant.parse(to) : null;
|
||||
|
||||
LogSearchRequest request = new LogSearchRequest(
|
||||
searchText, levels, application, instanceId, exchangeId,
|
||||
logger, env.slug(), sources, fromInstant, toInstant, cursor, limit, sort);
|
||||
logger, env.slug(), sources, fromInstant, toInstant, cursor, limit, sort,
|
||||
instanceIdList);
|
||||
|
||||
LogSearchResponse result = logIndex.search(request);
|
||||
|
||||
|
||||
@@ -122,6 +122,14 @@ public class ClickHouseLogStore implements LogIndex {
|
||||
baseParams.add(request.instanceId());
|
||||
}
|
||||
|
||||
if (request.instanceIds() != null && !request.instanceIds().isEmpty()) {
|
||||
String placeholders = String.join(", ", Collections.nCopies(request.instanceIds().size(), "?"));
|
||||
baseConditions.add("instance_id IN (" + placeholders + ")");
|
||||
for (String id : request.instanceIds()) {
|
||||
baseParams.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.exchangeId() != null && !request.exchangeId().isEmpty()) {
|
||||
baseConditions.add("(exchange_id = ?" +
|
||||
" OR (mapContains(mdc, 'cameleer.exchangeId') AND mdc['cameleer.exchangeId'] = ?)" +
|
||||
@@ -281,6 +289,14 @@ public class ClickHouseLogStore implements LogIndex {
|
||||
params.add(request.instanceId());
|
||||
}
|
||||
|
||||
if (request.instanceIds() != null && !request.instanceIds().isEmpty()) {
|
||||
String placeholders = String.join(", ", Collections.nCopies(request.instanceIds().size(), "?"));
|
||||
conditions.add("instance_id IN (" + placeholders + ")");
|
||||
for (String id : request.instanceIds()) {
|
||||
params.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.exchangeId() != null && !request.exchangeId().isEmpty()) {
|
||||
conditions.add("(exchange_id = ?" +
|
||||
" OR (mapContains(mdc, 'cameleer.exchangeId') AND mdc['cameleer.exchangeId'] = ?)" +
|
||||
|
||||
Reference in New Issue
Block a user