Skip to content

Commit 1211386

Browse files
authored
feat: add colors to event patterns based on severitytext (#841)
Ref: HDX-1738
1 parent d72d1d2 commit 1211386

File tree

6 files changed

+36
-3
lines changed

6 files changed

+36
-3
lines changed

.changeset/thick-melons-film.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/app": patch
3+
---
4+
5+
add severitytext coloring to event patterns

packages/app/src/DBSearchPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ function DBSearchPage() {
15791579
analysisMode === 'results' && (
15801580
<DBSqlRowTable
15811581
config={dbSqlRowTableConfig}
1582+
sourceId={searchedConfig.source ?? ''}
15821583
onRowExpandClick={onRowExpandClick}
15831584
highlightedLineId={rowId ?? undefined}
15841585
enabled={isReady}

packages/app/src/components/DBRowTable.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ import { useTableMetadata } from '@/hooks/useMetadata';
4747
import useOffsetPaginatedQuery from '@/hooks/useOffsetPaginatedQuery';
4848
import { useGroupedPatterns } from '@/hooks/usePatterns';
4949
import useRowWhere from '@/hooks/useRowWhere';
50+
import { useSource } from '@/source';
5051
import { UNDEFINED_WIDTH } from '@/tableUtils';
5152
import { FormatTime } from '@/useFormatTime';
5253
import { useUserPreferences } from '@/useUserPreferences';
5354
import {
5455
getLogLevelClass,
56+
logLevelColor,
5557
useLocalStorage,
5658
usePrevious,
5759
useWindowSize,
@@ -363,7 +365,7 @@ export const RawLogTable = memo(
363365
<PatternTrendChart
364366
data={value.data}
365367
dateRange={value.dateRange}
366-
// color={color}
368+
color={logLevelColor(info.row.original.severityText)}
367369
/>
368370
</div>
369371
);
@@ -898,6 +900,7 @@ export function selectColumnMapWithoutAdditionalKeys(
898900

899901
export function DBSqlRowTable({
900902
config,
903+
sourceId,
901904
onError,
902905
onRowExpandClick,
903906
highlightedLineId,
@@ -908,6 +911,7 @@ export function DBSqlRowTable({
908911
denoiseResults = false,
909912
}: {
910913
config: ChartConfigWithDateRange;
914+
sourceId?: string;
911915
onRowExpandClick?: (where: string) => void;
912916
highlightedLineId: string | undefined;
913917
queryKeyPrefix?: string;
@@ -990,11 +994,13 @@ export function DBSqlRowTable({
990994
}
991995
}, [isError, onError, error]);
992996

997+
const { data: source } = useSource({ id: sourceId });
993998
const patternColumn = columns[columns.length - 1];
994999
const groupedPatterns = useGroupedPatterns({
9951000
config,
9961001
samples: 10_000,
9971002
bodyValueExpression: patternColumn ?? '',
1003+
severityTextExpression: source?.severityTextExpression ?? '',
9981004
totalCount: undefined,
9991005
enabled: denoiseResults,
10001006
});

packages/app/src/components/PatternSidePanel.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DrawerBody, DrawerHeader } from '@/components/DrawerUtils';
1010
import { Pattern } from '@/hooks/usePatterns';
1111
import {
1212
PATTERN_COLUMN_ALIAS,
13+
SEVERITY_TEXT_COLUMN_ALIAS,
1314
TIMESTAMP_COLUMN_ALIAS,
1415
} from '@/hooks/usePatterns';
1516
import useRowWhere from '@/hooks/useRowWhere';
@@ -43,6 +44,7 @@ export default function PatternSidePanel({
4344
const map = new Map<string, { _type: JSDataType | null }>([
4445
[TIMESTAMP_COLUMN_ALIAS, { _type: JSDataType.Date }],
4546
[PATTERN_COLUMN_ALIAS, { _type: JSDataType.String }],
47+
[SEVERITY_TEXT_COLUMN_ALIAS, { _type: JSDataType.String }],
4648
[serviceNameExpression, { _type: JSDataType.String }],
4749
]);
4850
return map;
@@ -52,6 +54,7 @@ export default function PatternSidePanel({
5254
return {
5355
[TIMESTAMP_COLUMN_ALIAS]: 'Timestamp',
5456
[serviceNameExpression]: 'Service',
57+
[SEVERITY_TEXT_COLUMN_ALIAS]: 'level',
5558
[PATTERN_COLUMN_ALIAS]: 'Body',
5659
};
5760
}, [serviceNameExpression]);
@@ -60,6 +63,7 @@ export default function PatternSidePanel({
6063
return [
6164
TIMESTAMP_COLUMN_ALIAS,
6265
serviceNameExpression,
66+
SEVERITY_TEXT_COLUMN_ALIAS,
6367
PATTERN_COLUMN_ALIAS,
6468
];
6569
}, [serviceNameExpression]);

packages/app/src/components/PatternTable.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default function PatternTable({
3939
config,
4040
samples: SAMPLES,
4141
bodyValueExpression,
42+
severityTextExpression: source?.severityTextExpression ?? '',
4243
totalCount,
4344
});
4445

@@ -57,7 +58,12 @@ export default function PatternTable({
5758
wrapLines={true}
5859
isLoading={isLoading}
5960
rows={sortedGroupedResults ?? []}
60-
displayedColumns={['__hdx_pattern_trend', 'countStr', 'pattern']}
61+
displayedColumns={[
62+
'__hdx_pattern_trend',
63+
'countStr',
64+
'severityText',
65+
'pattern',
66+
]}
6167
onRowExpandClick={row => setSelectedPattern(row as Pattern)}
6268
hasNextPage={false}
6369
fetchNextPage={() => {}}
@@ -68,6 +74,7 @@ export default function PatternTable({
6874
__hdx_pattern_trend: 'Trend',
6975
countStr: 'Count',
7076
pattern: 'Pattern',
77+
severityText: 'level',
7178
}}
7279
/>
7380
{selectedPattern && source && (

packages/app/src/hooks/usePatterns.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ async function mineEventPatterns(logs: string[], pyodide: any) {
9898

9999
export const PATTERN_COLUMN_ALIAS = '__hdx_pattern_field';
100100
export const TIMESTAMP_COLUMN_ALIAS = '__hdx_timestamp';
101+
export const SEVERITY_TEXT_COLUMN_ALIAS = '__hdx_severity_text';
101102

102103
export type SampleLog = {
103104
[PATTERN_COLUMN_ALIAS]: string;
@@ -112,15 +113,17 @@ export type Pattern = {
112113
samples: SampleLog[];
113114
};
114115

115-
export function usePatterns({
116+
function usePatterns({
116117
config,
117118
samples,
118119
bodyValueExpression,
120+
severityTextExpression,
119121
enabled = true,
120122
}: {
121123
config: ChartConfigWithDateRange;
122124
samples: number;
123125
bodyValueExpression: string;
126+
severityTextExpression?: string;
124127
enabled?: boolean;
125128
}) {
126129
const configWithPrimaryAndPartitionKey = useConfigWithPrimaryAndPartitionKey({
@@ -129,6 +132,9 @@ export function usePatterns({
129132
select: [
130133
`${bodyValueExpression} as ${PATTERN_COLUMN_ALIAS}`,
131134
`${config.timestampValueExpression} as ${TIMESTAMP_COLUMN_ALIAS}`,
135+
...(severityTextExpression
136+
? [`${severityTextExpression} as ${SEVERITY_TEXT_COLUMN_ALIAS}`]
137+
: []),
132138
].join(','),
133139
// TODO: Proper sampling
134140
orderBy: [{ ordering: 'DESC', valueExpression: 'rand()' }],
@@ -186,19 +192,22 @@ export function useGroupedPatterns({
186192
config,
187193
samples,
188194
bodyValueExpression,
195+
severityTextExpression,
189196
totalCount,
190197
enabled = true,
191198
}: {
192199
config: ChartConfigWithDateRange;
193200
samples: number;
194201
bodyValueExpression: string;
202+
severityTextExpression?: string;
195203
totalCount?: number;
196204
enabled?: boolean;
197205
}) {
198206
const { data: results, isFetching } = usePatterns({
199207
config,
200208
samples,
201209
bodyValueExpression,
210+
severityTextExpression,
202211
enabled,
203212
});
204213
const columnMap = useMemo(() => {
@@ -258,6 +267,7 @@ export function useGroupedPatterns({
258267
pattern: rows[rows.length - 1].__hdx_pattern, // last pattern is usually the most up to date templated pattern
259268
count,
260269
countStr: `~${count}`,
270+
severityText: rows[rows.length - 1].__hdx_severity_text, // last severitytext is usually representative of the entire pattern set
261271
samples: rows,
262272
__hdx_pattern_trend: {
263273
data: Object.entries(bucketCounts).map(([bucket, count]) => ({

0 commit comments

Comments
 (0)