Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
58fbcad
feat: add initial types for window lookback
mrkaye97 Jun 16, 2026
108e442
feat: initial backend wiring using alert history
mrkaye97 Jun 16, 2026
d54dbc8
feat: update alert configuration modal(s)
mrkaye97 Jun 16, 2026
897fa74
feat: write a couple of tests
mrkaye97 Jun 16, 2026
4914f98
fix: typo
mrkaye97 Jun 16, 2026
fa2ea77
fix: backwards compat
mrkaye97 Jun 16, 2026
25a403d
fix: write `fired=false` back to mongo
mrkaye97 Jun 16, 2026
07079ae
fix: naming
mrkaye97 Jun 16, 2026
e78fd96
refactor: group key can be optional
mrkaye97 Jun 16, 2026
7687415
Merge branch 'main' into mk/add-multi-window-lookback-alerts
mrkaye97 Jun 17, 2026
3413bfa
Merge branch 'main' into mk/add-multi-window-lookback-alerts
karl-power Jun 19, 2026
a55f73e
chore: lint
mrkaye97 Jun 19, 2026
436207e
feat: initial pending state work
mrkaye97 Jun 22, 2026
cc0dc5b
chore: changeset
mrkaye97 Jun 22, 2026
8e2dc73
chore: add comment + more windows
mrkaye97 Jun 22, 2026
d0c8adc
Merge branch 'main' into mk/add-multi-window-lookback-alerts
mrkaye97 Jun 22, 2026
a114014
fix: make the alert badge orange
mrkaye97 Jun 23, 2026
3394ecd
fix: show state as pending in grouped history if there's a pending alert
mrkaye97 Jun 23, 2026
1db6427
fix: show pending state in alert history as orange
mrkaye97 Jun 23, 2026
7c6eb3f
fix: handle pending states properly in missing group loop
mrkaye97 Jun 23, 2026
a360ff3
Merge branch 'main' into mk/add-multi-window-lookback-alerts
mrkaye97 Jun 23, 2026
5d0c9ce
fix: greptile comment
mrkaye97 Jun 23, 2026
82f9c11
fix: truthiness
mrkaye97 Jun 23, 2026
bee6ae0
fix: undefined -> null
mrkaye97 Jun 23, 2026
bb3e5fa
fix: use exact time match
mrkaye97 Jun 23, 2026
06ed306
Merge branch 'main' into mk/add-multi-window-lookback-alerts
karl-power Jun 24, 2026
1ed62b0
chore: lint
mrkaye97 Jun 24, 2026
79d737c
fix: one more nullish zod field
mrkaye97 Jun 24, 2026
2b5dfc3
fix: one more use of `nullish`
mrkaye97 Jun 24, 2026
75d9dc2
Merge branch 'main' into mk/add-multi-window-lookback-alerts
karl-power Jun 24, 2026
022d6ef
Merge branch 'main' into mk/add-multi-window-lookback-alerts
karl-power Jun 25, 2026
fad2aae
one db query per alert, shared queue
karl-power Jun 25, 2026
659fdd9
Merge branch 'main' into mk/add-multi-window-lookback-alerts
karl-power Jun 26, 2026
41b9820
fix: move to advanced settings
mrkaye97 Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/rare-spoons-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@hyperdx/common-utils": minor
"@hyperdx/api": minor
"@hyperdx/app": minor
---

Adding consecutive-window configuration to alerts, so that you can specify a condition like "only fire this alert after some condition is met for N consecutive windows." This helps prevent flaky alerts (and pages), and cut down on alert noise in many cases.

Also adds a `PENDING` alert state for alarms that _will_ fire if current trends continue.
16 changes: 13 additions & 3 deletions packages/api/src/controllers/alertHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,24 @@ type GroupedAlertHistory = {
lastValues: IAlertHistory['lastValues'][];
};

function groupStateToOverallState(states: string[]): AlertState {
if (states.includes(AlertState.ALERT)) {
return AlertState.ALERT;
}

if (states.includes(AlertState.PENDING)) {
return AlertState.PENDING;
}

return AlertState.OK;
}

function mapGroupedHistories(
groupedHistories: GroupedAlertHistory[],
): Omit<IAlertHistory, 'alert'>[] {
return groupedHistories.map(group => ({
createdAt: group._id,
state: group.states.includes(AlertState.ALERT)
? AlertState.ALERT
: AlertState.OK,
state: groupStateToOverallState(group.states),
counts: group.counts,
lastValues: group.lastValues
.flat()
Expand Down
3 changes: 3 additions & 0 deletions packages/api/src/controllers/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ const makeAlert = (alert: AlertInput, userId?: ObjectId): Partial<IAlert> => {
// Chart alerts
dashboard: alert.dashboardId as unknown as ObjectId,
tileId: alert.tileId,

// Multi-window alerting
numConsecutiveWindows: alert.numConsecutiveWindows ?? null,
};
};

Expand Down
9 changes: 9 additions & 0 deletions packages/api/src/models/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export enum AlertState {
DISABLED = 'DISABLED',
INSUFFICIENT_DATA = 'INSUFFICIENT_DATA',
OK = 'OK',
PENDING = 'PENDING',
}

export interface IAlertError {
Expand Down Expand Up @@ -84,6 +85,9 @@ export interface IAlert {
until: Date;
};

// Multi-window alerting: fire only after N violations in M consecutive windows
numConsecutiveWindows?: number | null;

// Errors recorded during the most recent execution
executionErrors?: IAlertError[];
createdAt: Date;
Expand Down Expand Up @@ -190,6 +194,11 @@ const AlertSchema = new Schema<IAlert>(
type: String,
required: false,
},
numConsecutiveWindows: {
type: Number,
required: false,
min: 1,
},
silenced: {
required: false,
type: {
Expand Down
5 changes: 5 additions & 0 deletions packages/api/src/models/alertHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface IAlertHistory {
state: AlertState;
lastValues: { startTime: Date; count: number }[];
group?: string; // For group-by alerts, stores the group identifier
fired?: boolean;
}

const AlertHistorySchema = new Schema<IAlertHistory>({
Expand Down Expand Up @@ -45,6 +46,10 @@ const AlertHistorySchema = new Schema<IAlertHistory>({
type: String,
required: false,
},
fired: {
type: Boolean,
required: false,
},
});

AlertHistorySchema.index(
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/routers/api/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const formatAlertResponse = (
'createdAt',
'updatedAt',
'executionErrors',
'numConsecutiveWindows',
]),
};
};
Expand Down
Loading