Alert Triage
An alert queue grouped by fingerprint. A flapping check fires two hundred times, and an ungrouped list buries every other alert underneath it — which is how real pages get missed.
src/components/ui/alert-triage.tsxAbout
From the component's own source, where it was written.
An alert queue, grouped by fingerprint.
Grouping is the whole job. A flapping check fires two hundred times and the useful view is "this one alert, 200 occurrences" — an ungrouped list buries every other alert underneath it, which is how real pages get missed.
Bulk actions report ids and never mutate the list. Acknowledging is a server-side decision, and a queue that optimistically hid rows would show two responders different pictures of the same incident.
Install
npx astralyx-ui add alert-triage
Usage
import { AlertTriage } from '@/components/ui/alert-triage'
<AlertTriage alerts={alerts} onAcknowledge={ack} onSilence={silence} />Composer
Change the props and the source below follows.
- Criticalcheckout service returning 5xx×214
prometheuslast first
- Criticaldatabase connection pool saturated×12
prometheuslast
- Warningdisk usage above 85% on runner-04Acked
node-exporterlast
- InfoTLS certificate expires in 14 days
blackboxlast
<AlertTriage alerts={alerts} onAcknowledge={ack} onSilence={silence} />Examples
Queue
<AlertTriage alerts={alerts} onAcknowledge={ack} onSilence={silence} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
AlertTriage
Extends Omit<ComponentProps<'div'>, 'onSelect'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| alerts | Alert[] | required | { id, title, severity, fingerprint?, count?, source?, firstSeen?, lastSeen?, acknowledged?, detail? }. |
| onAcknowledge | (ids: string[]) => void | — | Report the ids of every member of the selected groups. Nothing is hidden optimistically — that would show two responders different pictures of one incident. |
| onSilence | (ids: string[]) => void | — | Report the ids of every member of the selected groups. Nothing is hidden optimistically — that would show two responders different pictures of one incident. |
| now | Date | — | — |
| selectAllLabel | string | 'Select all alerts' | — |
| clearSelectionLabel | string | 'Clear selection' | — |
| selectAlertLabel | (fingerprint: string) => string | DEFAULT_SELECT_ALERT_LABEL | — |
| toggleDetailLabel | (open: boolean) => string | DEFAULT_TOGGLE_DETAIL_LABEL | — |
| selectedLabel | (count: number) => ReactNode | DEFAULT_SELECTED_LABEL | — |
| summaryLabel | (total: number, critical: number) => ReactNode | DEFAULT_SUMMARY_LABEL | Roll-up shown when nothing is selected. |
| acknowledgeLabel | ReactNode | 'Acknowledge' | — |
| silenceLabel | ReactNode | 'Silence' | — |
| acknowledgedLabel | ReactNode | 'Acked' | — |
| lastSeenLabel | ReactNode | 'last' | Precedes the last-seen time. |
| firstSeenLabel | ReactNode | 'first' | Precedes the first-seen time. |
Types
Alert
An alert queue, grouped by fingerprint.
| Field | Type | Description |
|---|---|---|
| id | string | — |
| title | ReactNode | — |
| severity | 'critical' | 'warning' | 'info' | — |
| fingerprint? | string | Alerts sharing one collapse into a single row with an occurrence count. Falls back to the id. |
| count? | number | — |
| source? | string | — |
| firstSeen? | Date | — |
| lastSeen? | Date | — |
| acknowledged? | boolean | — |
| detail? | ReactNode | — |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| ordering | severity | Critical first. Order within a group is the caller’s; only the roll-up is computed. |