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:
hsiegeln
2026-04-23 12:41:09 +02:00
parent 2312a7304d
commit 382e1801a7
7 changed files with 253 additions and 23 deletions

View File

@@ -9,7 +9,7 @@ import java.util.List;
* @param q free-text search across message and stack trace
* @param levels log level filter (e.g. ["WARN","ERROR"]), OR-joined
* @param application application ID filter (nullable = all apps)
* @param instanceId agent instance ID filter
* @param instanceId agent instance ID filter (single value; coexists with instanceIds)
* @param exchangeId Camel exchange ID filter
* @param logger logger name substring filter
* @param environment optional environment filter (e.g. "dev", "staging", "prod")
@@ -19,6 +19,9 @@ import java.util.List;
* @param cursor ISO timestamp cursor for keyset pagination
* @param limit page size (1-500, default 100)
* @param sort sort direction: "asc" or "desc" (default "desc")
* @param instanceIds multi-value instance ID filter (IN clause); scopes logs to one deployment's
* replicas when provided. Both instanceId and instanceIds may coexist — both
* conditions apply (AND). Empty/null means no additional filtering.
*/
public record LogSearchRequest(
String q,
@@ -33,7 +36,8 @@ public record LogSearchRequest(
Instant to,
String cursor,
int limit,
String sort
String sort,
List<String> instanceIds
) {
private static final int DEFAULT_LIMIT = 100;
@@ -45,5 +49,6 @@ public record LogSearchRequest(
if (sort == null || !"asc".equalsIgnoreCase(sort)) sort = "desc";
if (levels == null) levels = List.of();
if (sources == null) sources = List.of();
if (instanceIds == null) instanceIds = List.of();
}
}