Skip to content

Commit 4b1f9af

Browse files
authored
1 parent 37c0949 commit 4b1f9af

File tree

6 files changed

+477
-247
lines changed

6 files changed

+477
-247
lines changed

packages/app/src/DBSearchPage.tsx

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,18 @@ function DBSearchPage() {
503503
}
504504
}, [analysisMode, setIsLive]);
505505

506+
const [denoiseResults, _setDenoiseResults] = useQueryState(
507+
'denoise',
508+
parseAsBoolean.withDefault(false),
509+
);
510+
const setDenoiseResults = useCallback(
511+
(value: boolean) => {
512+
setIsLive(false);
513+
_setDenoiseResults(value);
514+
},
515+
[setIsLive, _setDenoiseResults],
516+
);
517+
506518
const {
507519
control,
508520
watch,
@@ -719,11 +731,11 @@ function DBSearchPage() {
719731
const onTableScroll = useCallback(
720732
(scrollTop: number) => {
721733
// If the user scrolls a bit down, kick out of live mode
722-
if (scrollTop > 16) {
734+
if (scrollTop > 16 && isLive) {
723735
setIsLive(false);
724736
}
725737
},
726-
[setIsLive],
738+
[isLive, setIsLive],
727739
);
728740

729741
const onRowExpandClick = useCallback(
@@ -1247,6 +1259,8 @@ function DBSearchPage() {
12471259
>
12481260
<ErrorBoundary message="Unable to render search filters">
12491261
<DBSearchPageFilters
1262+
denoiseResults={denoiseResults}
1263+
setDenoiseResults={setDenoiseResults}
12501264
isLive={isLive}
12511265
analysisMode={analysisMode}
12521266
setAnalysisMode={setAnalysisMode}
@@ -1534,25 +1548,31 @@ function DBSearchPage() {
15341548
</>
15351549
) : (
15361550
<>
1537-
{shouldShowLiveModeHint && analysisMode === 'results' && (
1538-
<div
1539-
className="d-flex justify-content-center"
1540-
style={{ height: 0 }}
1541-
>
1551+
{shouldShowLiveModeHint &&
1552+
analysisMode === 'results' &&
1553+
denoiseResults != true && (
15421554
<div
1543-
style={{ position: 'relative', top: -20, zIndex: 2 }}
1555+
className="d-flex justify-content-center"
1556+
style={{ height: 0 }}
15441557
>
1545-
<Button
1546-
size="compact-xs"
1547-
variant="outline"
1548-
onClick={handleResumeLiveTail}
1558+
<div
1559+
style={{
1560+
position: 'relative',
1561+
top: -20,
1562+
zIndex: 2,
1563+
}}
15491564
>
1550-
<i className="bi text-success bi-lightning-charge-fill me-2" />
1551-
Resume Live Tail
1552-
</Button>
1565+
<Button
1566+
size="compact-xs"
1567+
variant="outline"
1568+
onClick={handleResumeLiveTail}
1569+
>
1570+
<i className="bi text-success bi-lightning-charge-fill me-2" />
1571+
Resume Live Tail
1572+
</Button>
1573+
</div>
15531574
</div>
1554-
</div>
1555-
)}
1575+
)}
15561576
{chartConfig &&
15571577
dbSqlRowTableConfig &&
15581578
analysisMode === 'results' && (
@@ -1565,6 +1585,7 @@ function DBSearchPage() {
15651585
queryKeyPrefix={QUERY_KEY_PREFIX}
15661586
onScroll={onTableScroll}
15671587
onError={handleTableError}
1588+
denoiseResults={denoiseResults}
15681589
/>
15691590
)}
15701591
</>

packages/app/src/components/DBRowTable.tsx

Lines changed: 120 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ import {
2727
} from '@hyperdx/common-utils/dist/types';
2828
import { splitAndTrimWithBracket } from '@hyperdx/common-utils/dist/utils';
2929
import { Box, Code, Flex, Text } from '@mantine/core';
30-
import { FetchNextPageOptions } from '@tanstack/react-query';
30+
import {
31+
FetchNextPageOptions,
32+
useQuery,
33+
useQueryClient,
34+
} from '@tanstack/react-query';
3135
import {
3236
ColumnDef,
3337
ColumnResizeMode,
@@ -41,6 +45,7 @@ import { useVirtualizer } from '@tanstack/react-virtual';
4145

4246
import { useTableMetadata } from '@/hooks/useMetadata';
4347
import useOffsetPaginatedQuery from '@/hooks/useOffsetPaginatedQuery';
48+
import { useGroupedPatterns } from '@/hooks/usePatterns';
4449
import useRowWhere from '@/hooks/useRowWhere';
4550
import { UNDEFINED_WIDTH } from '@/tableUtils';
4651
import { FormatTime } from '@/useFormatTime';
@@ -900,6 +905,7 @@ export function DBSqlRowTable({
900905
isLive = false,
901906
queryKeyPrefix,
902907
onScroll,
908+
denoiseResults = false,
903909
}: {
904910
config: ChartConfigWithDateRange;
905911
onRowExpandClick?: (where: string) => void;
@@ -909,6 +915,7 @@ export function DBSqlRowTable({
909915
isLive?: boolean;
910916
onScroll?: (scrollTop: number) => void;
911917
onError?: (error: Error | ClickHouseQueryError) => void;
918+
denoiseResults?: boolean;
912919
}) {
913920
const mergedConfig = useConfigWithPrimaryAndPartitionKey(config);
914921

@@ -964,7 +971,7 @@ export function DBSqlRowTable({
964971
});
965972
return newRow;
966973
});
967-
}, [data, objectTypeColumns]);
974+
}, [data, objectTypeColumns, columnMap]);
968975

969976
const aliasMap = chSqlToAliasMap(data?.chSql ?? { sql: '', params: {} });
970977

@@ -983,23 +990,117 @@ export function DBSqlRowTable({
983990
}
984991
}, [isError, onError, error]);
985992

993+
const patternColumn = columns[columns.length - 1];
994+
const groupedPatterns = useGroupedPatterns({
995+
config,
996+
samples: 10_000,
997+
bodyValueExpression: patternColumn ?? '',
998+
totalCount: undefined,
999+
enabled: denoiseResults,
1000+
});
1001+
const noisyPatterns = useQuery({
1002+
queryKey: ['noisy-patterns', config],
1003+
queryFn: async () => {
1004+
return Object.values(groupedPatterns.data).filter(
1005+
p => p.count / (groupedPatterns.sampledRowCount ?? 1) > 0.1,
1006+
);
1007+
},
1008+
enabled:
1009+
denoiseResults &&
1010+
groupedPatterns.data != null &&
1011+
Object.values(groupedPatterns.data).length > 0 &&
1012+
groupedPatterns.miner != null,
1013+
});
1014+
const noisyPatternIds = useMemo(() => {
1015+
return noisyPatterns.data?.map(p => p.id) ?? [];
1016+
}, [noisyPatterns.data]);
1017+
1018+
const queryClient = useQueryClient();
1019+
1020+
const denoisedRows = useQuery({
1021+
queryKey: [
1022+
'denoised-rows',
1023+
config,
1024+
processedRows,
1025+
noisyPatternIds,
1026+
patternColumn,
1027+
],
1028+
queryFn: async () => {
1029+
// No noisy patterns, so no need to denoise
1030+
if (noisyPatternIds.length === 0) {
1031+
return processedRows;
1032+
}
1033+
1034+
const matchedLogs = await groupedPatterns.miner?.matchLogs(
1035+
processedRows.map(row => row[patternColumn]),
1036+
);
1037+
return processedRows.filter((row, i) => {
1038+
const match = matchedLogs?.[i];
1039+
return !noisyPatternIds.includes(`${match}`);
1040+
});
1041+
},
1042+
placeholderData: (previousData, previousQuery) => {
1043+
// If it's the same search, but new data, return the previous data while we load
1044+
if (
1045+
previousQuery?.queryKey?.[0] === 'denoised-rows' &&
1046+
previousQuery?.queryKey?.[1] === config
1047+
) {
1048+
return previousData;
1049+
}
1050+
return undefined;
1051+
},
1052+
enabled:
1053+
denoiseResults &&
1054+
noisyPatterns.isSuccess &&
1055+
processedRows.length > 0 &&
1056+
groupedPatterns.miner != null,
1057+
});
1058+
1059+
const isLoading = denoiseResults
1060+
? isFetching ||
1061+
denoisedRows.isFetching ||
1062+
noisyPatterns.isFetching ||
1063+
groupedPatterns.isLoading
1064+
: isFetching;
1065+
9861066
return (
987-
<RawLogTable
988-
isLive={isLive}
989-
wrapLines={false}
990-
displayedColumns={columns}
991-
highlightedLineId={highlightedLineId}
992-
rows={processedRows}
993-
isLoading={isFetching}
994-
fetchNextPage={fetchNextPage}
995-
// onPropertySearchClick={onPropertySearchClick}
996-
hasNextPage={hasNextPage}
997-
onRowExpandClick={_onRowExpandClick}
998-
onScroll={onScroll}
999-
generateRowId={getRowWhere}
1000-
isError={isError}
1001-
error={error ?? undefined}
1002-
columnTypeMap={columnMap}
1003-
/>
1067+
<>
1068+
{denoiseResults && (
1069+
<Box mb="xxs" px="sm" mt="-24px">
1070+
<Text fw="bold" fz="xs" mb="xxs">
1071+
Removed Noisy Event Patterns
1072+
</Text>
1073+
<Box mah={100} style={{ overflow: 'auto' }}>
1074+
{noisyPatterns.data?.map(p => (
1075+
<Text c="gray.3" fz="xs" key={p.id}>
1076+
{p.pattern}
1077+
</Text>
1078+
))}
1079+
{noisyPatternIds.length === 0 && (
1080+
<Text c="gray.3" fz="xs">
1081+
No noisy patterns found
1082+
</Text>
1083+
)}
1084+
</Box>
1085+
</Box>
1086+
)}
1087+
<RawLogTable
1088+
isLive={isLive}
1089+
wrapLines={false}
1090+
displayedColumns={columns}
1091+
highlightedLineId={highlightedLineId}
1092+
rows={denoiseResults ? (denoisedRows?.data ?? []) : processedRows}
1093+
isLoading={isLoading}
1094+
fetchNextPage={fetchNextPage}
1095+
// onPropertySearchClick={onPropertySearchClick}
1096+
hasNextPage={hasNextPage}
1097+
onRowExpandClick={_onRowExpandClick}
1098+
onScroll={onScroll}
1099+
generateRowId={getRowWhere}
1100+
isError={isError}
1101+
error={error ?? undefined}
1102+
columnTypeMap={columnMap}
1103+
/>
1104+
</>
10041105
);
10051106
}

packages/app/src/components/DBSearchPageFilters.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,17 @@ export const DBSearchPageFilters = ({
326326
setAnalysisMode,
327327
sourceId,
328328
showDelta,
329+
denoiseResults,
330+
setDenoiseResults,
329331
}: {
330332
analysisMode: 'results' | 'delta' | 'pattern';
331333
setAnalysisMode: (mode: 'results' | 'delta' | 'pattern') => void;
332334
isLive: boolean;
333335
chartConfig: ChartConfigWithDateRange;
334336
sourceId?: string;
335337
showDelta: boolean;
338+
denoiseResults: boolean;
339+
setDenoiseResults: (denoiseResults: boolean) => void;
336340
} & FilterStateHook) => {
337341
const { toggleFilterPin, isFilterPinned } = usePinnedFilters(
338342
sourceId ?? null,
@@ -489,6 +493,28 @@ export const DBSearchPageFilters = ({
489493
)}
490494
</Flex>
491495

496+
{analysisMode === 'results' && (
497+
<Checkbox
498+
size={13 as any}
499+
checked={denoiseResults}
500+
ms="6px"
501+
label={
502+
<Tooltip
503+
openDelay={200}
504+
color="gray"
505+
position="right"
506+
withArrow
507+
label="Denoise results will visually remove events matching common event patterns from the results table."
508+
>
509+
<Text size="xs" c="gray.3" mt="-1px">
510+
<i className="bi bi-noise-reduction"></i> Denoise Results
511+
</Text>
512+
</Tooltip>
513+
}
514+
onChange={() => setDenoiseResults(!denoiseResults)}
515+
/>
516+
)}
517+
492518
{isLoading || isFacetsLoading ? (
493519
<Flex align="center" justify="center">
494520
<Loader size="xs" color="gray" />

0 commit comments

Comments
 (0)