@@ -27,7 +27,11 @@ import {
27
27
} from '@hyperdx/common-utils/dist/types' ;
28
28
import { splitAndTrimWithBracket } from '@hyperdx/common-utils/dist/utils' ;
29
29
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' ;
31
35
import {
32
36
ColumnDef ,
33
37
ColumnResizeMode ,
@@ -41,6 +45,7 @@ import { useVirtualizer } from '@tanstack/react-virtual';
41
45
42
46
import { useTableMetadata } from '@/hooks/useMetadata' ;
43
47
import useOffsetPaginatedQuery from '@/hooks/useOffsetPaginatedQuery' ;
48
+ import { useGroupedPatterns } from '@/hooks/usePatterns' ;
44
49
import useRowWhere from '@/hooks/useRowWhere' ;
45
50
import { UNDEFINED_WIDTH } from '@/tableUtils' ;
46
51
import { FormatTime } from '@/useFormatTime' ;
@@ -900,6 +905,7 @@ export function DBSqlRowTable({
900
905
isLive = false ,
901
906
queryKeyPrefix,
902
907
onScroll,
908
+ denoiseResults = false ,
903
909
} : {
904
910
config : ChartConfigWithDateRange ;
905
911
onRowExpandClick ?: ( where : string ) => void ;
@@ -909,6 +915,7 @@ export function DBSqlRowTable({
909
915
isLive ?: boolean ;
910
916
onScroll ?: ( scrollTop : number ) => void ;
911
917
onError ?: ( error : Error | ClickHouseQueryError ) => void ;
918
+ denoiseResults ?: boolean ;
912
919
} ) {
913
920
const mergedConfig = useConfigWithPrimaryAndPartitionKey ( config ) ;
914
921
@@ -964,7 +971,7 @@ export function DBSqlRowTable({
964
971
} ) ;
965
972
return newRow ;
966
973
} ) ;
967
- } , [ data , objectTypeColumns ] ) ;
974
+ } , [ data , objectTypeColumns , columnMap ] ) ;
968
975
969
976
const aliasMap = chSqlToAliasMap ( data ?. chSql ?? { sql : '' , params : { } } ) ;
970
977
@@ -983,23 +990,117 @@ export function DBSqlRowTable({
983
990
}
984
991
} , [ isError , onError , error ] ) ;
985
992
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
+
986
1066
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
+ </ >
1004
1105
) ;
1005
1106
}
0 commit comments