Skip to content

Commit af35657

Browse files
committed
[local-explorer-ui] match ids by prefix (not substring) in free-text search
Free-text search matched trace/span ids with %q% (substring anywhere), so on hex ids any short term like "de" matched almost every record and effectively disabled filtering. Match ids by prefix (q%), consistent with the trace:/span: filters, while keeping substring matching for names, messages, service, and attributes.
1 parent 7db34cc commit af35657

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

packages/local-explorer-ui/src/__tests__/observability/id-search.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ describe("listTraces id search", () => {
3434
expect(sql).toContain("SELECT trace_id FROM spans WHERE span_id LIKE ?");
3535
expect(params).toContain("def456%");
3636
});
37+
38+
test("free-text matches ids by prefix, names/attrs by substring", async ({
39+
expect,
40+
}) => {
41+
await listTraces({ search: "de" });
42+
const { params } = lastQuery();
43+
// ids: prefix only (no leading %), so a short hex term doesn't match all.
44+
expect(params).toContain("de%");
45+
expect(params).not.toContain("%de%de%");
46+
// names/attributes: substring.
47+
expect(params).toContain("%de%");
48+
});
3749
});
3850

3951
describe("listEvents id search", () => {
@@ -50,4 +62,15 @@ describe("listEvents id search", () => {
5062
expect(sql).toContain("l.span_id LIKE ?");
5163
expect(params).toContain("def456%");
5264
});
65+
66+
test("free-text matches ids by prefix, message/service by substring", async ({
67+
expect,
68+
}) => {
69+
await listEvents({ search: "de" });
70+
const { params } = lastQuery();
71+
// ids: prefix only.
72+
expect(params).toContain("de%");
73+
// message/operation/service: substring.
74+
expect(params).toContain("%de%");
75+
});
5376
});

packages/local-explorer-ui/src/utils/observability.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,13 @@ export function listTraces(filters: TraceFilters = {}): Promise<TraceRow[]> {
559559
const q = filters.search?.trim();
560560
if (q) {
561561
const like = `%${q}%`;
562+
// ids match as a prefix (like the trace:/span: filters) — a substring
563+
// match on hex ids means any short term matches almost everything.
564+
const idPrefix = `${q}%`;
562565
where.push(
563566
"(s.name LIKE ? OR s.trace_id LIKE ? OR s.trace_id IN (SELECT trace_id FROM spans WHERE name LIKE ? OR span_id LIKE ? OR json(attributes) LIKE ?))"
564567
);
565-
params.push(like, like, like, like, like);
568+
params.push(like, idPrefix, like, idPrefix, like);
566569
}
567570

568571
params.push(limit);
@@ -682,10 +685,13 @@ export function listEvents(filters: EventFilters = {}): Promise<LogEvent[]> {
682685
const q = filters.search?.trim();
683686
if (q) {
684687
const like = `%${q}%`;
688+
// ids match as a prefix (like the trace:/span: filters) — a substring
689+
// match on hex ids means any short term matches almost everything.
690+
const idPrefix = `${q}%`;
685691
where.push(
686692
"(l.message LIKE ? OR l.operation LIKE ? OR sp.service LIKE ? OR l.trace_id LIKE ? OR l.span_id LIKE ?)"
687693
);
688-
params.push(like, like, like, like, like);
694+
params.push(like, like, like, idPrefix, idPrefix);
689695
}
690696

691697
// Structured clauses from the filter modal. Fields map to a concrete log

0 commit comments

Comments
 (0)