Alert model
The alerter evaluates durable database state and creates one lifecycle record for each active condition. Alert policies are retired; routing now lives in tenant notification settings and each monitor.
| Alert kind | Signal | Resolution |
|---|---|---|
availability | A monitor reaches effective down state | Monitor becomes up, is disabled/deleted, or condition is manually resolved |
latency_anomaly | Recent successful latency breaches a learned baseline | Recent latency returns below the detector threshold |
host_metric | A metric series reported by an agent's collector breaches a configured metric rule | The series returns within the rule, the rule is removed, or the readings go stale |
mesh_edge | A directional location-mesh edge reaches down | That direction recovers |
tls_expiry | An HTTP monitor's certificate has fewer remaining validity days than tls_min_days_valid | A renewed certificate is observed, or the threshold is removed |
| Status | Meaning |
|---|---|
active | Condition is open and unacknowledged |
acknowledged | An operator has acknowledged the alert; the underlying condition remains open |
resolved | Alert lifecycle is closed |
Availability lifecycle
- A check failure first passes through the monitor's consecutive-failure confirmation and, when locations are selected, its location failure quorum.
- The alerter opens an availability alert only when effective state is
down, the monitor is enabled, and maintenance/rollup rules do not mute it. - The initial notification is sent through eligible routes after each route's configured delay.
- While the condition remains down, reminders are sent at the tenant reminder interval.
- When the monitor is fully
up, the alert resolves and resolution notifications go only to channels that previously received that alert.
suspect, unknown, and a newly degraded monitor do not open an availability alert. If a monitor moves from down to degraded after an alert opened, the alert remains open until the aggregate is fully up.
Location-aware availability alerts include failing-location context so operators can distinguish a regional failure from a broad outage.
Default and custom notification routing
- Tenant default routes
- An ordered list of active alert channels, each with
channel_id, display metadata, and a non-negativedelay_seconds. - Monitor
defaultmode - The monitor inherits the tenant's current default routes.
- Monitor
custommode - Only the monitor's assigned active channels are considered, with the delay stored on each assignment.
Delays implement escalation: a zero-delay route fires immediately, while a later route fires only if the alert is still open when its delay elapses. Resolution notifications are limited to routes that actually fired, avoiding a recovery message on a channel that never saw the outage.
Routing that resolves to nothing is not an error — an alert still opens, appears on the dashboard, and drives incidents and status pages; it simply notifies nobody. Because that is silent by design, every monitor read reports its effective reachability in alert_routing, and the dashboard counts affected monitors in ops_summary.unrouted_monitors.
| `alert_routing` field | Meaning |
|---|---|
reachable | False when an alert on this monitor would notify nobody |
source | custom or tenant_default when the monitor's own routing applies; group_rollup when a group rolls its alerts up, so that group's routing decides; members for a group that never alerts itself |
active_channels / assigned_channels | Routed channels that would deliver, and the total including inactive ones — an assignment to an inactive channel counts as assigned but never delivers |
reason | Why an unreachable monitor is unreachable: no_custom_channels, custom_channels_disabled, no_tenant_default_channels, tenant_default_channels_disabled, or group_rollup_unrouted |
rollup_group_id / rollup_group_name | The group whose routing applies, present only for group_rollup |
| Tenant notification setting | Default / constraints |
|---|---|
default_channels | Ordered channel assignments with non-negative delays |
alert_reminder_seconds | Defaults to 3,600; set 0 to disable reminders |
auto_create_incident | Defaults to false; verified for availability and latency-anomaly opening paths |
latency_anomaly_enabled | Defaults to false and also depends on the platform-level detector switch |
latency_baseline_window_hours | Defaults to 168 |
latency_anomaly_sensitivity | Defaults to 3.5 |
latency_anomaly_min_breach_seconds | Defaults to 120 |
latency_anomaly_min_delta_pct | Defaults to 20 (percent) |
dependency_suppression_enabled | Defaults to false. When true, a monitor whose upstream dependency is down opens its alert but sends no notification — see dependency-aware alerting. Monitors override it with dependency_suppression |
dependency_suppression_grace_seconds | Defaults to 120; 0 to 86,400. How long a suppressed downstream stays quiet after its upstream recovers before paging if still down |
Notification channels
| Plugin type | Configuration | Delivery |
|---|---|---|
email | to list and optional subject / plain-text / HTML body templates | Branded HTML plus plain-text email over the platform SMTP configuration |
slack | Approved HTTPS webhook_url on Slack webhook hosts | Slack incoming webhook |
discord | Approved Discord HTTPS webhook URL | Discord webhook |
teams | Approved Microsoft webhook URL | Teams/Workflow-compatible webhook |
generic_webhook | HTTPS url, optional hmac_secret, optional custom headers encoded as JSON | Structured Probara event JSON |
Generic webhooks include X-Probara-Event-Type and X-Probara-Idempotency-Key. When an HMAC secret is configured they also include X-Probara-Signature in sha256=... form. Receivers should verify the signature against the raw body and deduplicate by the idempotency key.
- Create a channel from a registered plugin and save its plugin-specific configuration.
- Use the channel test action before assigning production monitors. Tests send a real notification and require write permission. Email tests are served by the API process, so they need the same platform SMTP configuration as the alerter; without it the test reports
mailer not configuredeven when alert email is being delivered. - Activate or deactivate the channel. Inactive channels remain configured but are skipped for delivery.
- Assign it in tenant defaults or in a monitor's custom routing.
Email rendering and templates
With no template overrides, an email channel sends a multipart/alternative message: a branded HTML part and a plain-text part rendered from the same data, so text-only clients and mail archives never see markup. The HTML part is self-contained — inline styles, no remote images, no data: URIs — and adapts to the reader's light or dark theme. Both parts lead with a one-sentence summary of what happened, then the measurement that tripped the alert (observed vs. baseline latency, metric vs. threshold, certificate days remaining), the verbatim probe error, the likely root cause when the dependency graph identifies one, the failing locations of a multi-location monitor, and a metadata block with the trigger time, elapsed duration, and failed-check count.
Set APP_BASE_URL to the public origin of the operator UI and every alert email carries an "open the monitor" button (mesh-edge alerts link to the mesh matrix instead). Without it the button is omitted rather than pointing at a guessed host. SMTP_FROM_NAME sets the From display name and defaults to Probara Alerts.
| Channel field | Effect |
|---|---|
subject_template | Go text/template replacing the default [Alert Triggered] <monitor> subject. |
body_template | Go text/template replacing the plain-text body. Set on its own it sends a text-only message: an operator who wrote a specific text alert should not also receive unrelated generated markup alongside it. |
body_html_template | Go html/template replacing the built-in HTML design. Alert values are HTML-escaped; your markup is not. Combine it with body_template to control both parts. |
Templates receive the raw alert fields (monitor_name, status, kind, failure_count, last_error, triggered_at, resolved_at, tenant_id, metric_name, metric_value, threshold_value, baseline_latency_ms, observed_latency_ms, anomaly_score, root_cause_monitor_name, source_location_name, target_location_name, failing_locations) plus the presentation values the built-in email uses, so an override can reuse the same wording: label, status_label, summary, duration, triggered_at_human, resolved_at_human, action_url, action_label, and accent_color. A template that fails to parse or execute falls back to the built-in rendering — the alert still goes out and the error is logged.
Group alert rollup
A group monitor chooses one of two availability alert strategies. per_monitor lets members alert normally and suppresses an additional group alert. group suppresses member availability alerts covered by the group and emits one group-level alert while any effective member is down.
Under group rollup the group's routing is the routing that matters: a suppressed member's own channels never fire, so its alert_routing.source reports group_rollup and names the group. A member covered by several rollup groups is reachable if any of them delivers, since each group alerts on its own.
Latency anomaly alerts
The anomaly detector compares recent successful monitor-source latency with hourly successful-history baselines. It opens an alert only when latency exceeds the sensitivity threshold, minimum percent delta, and minimum breach duration configured for the tenant.
- The platform-wide latency detector must be enabled.
- The tenant's
latency_anomaly_enabledsetting must be true. - The monitor must be enabled, must not be a group, and must not be in maintenance.
- Enough retained successful data must exist to form a baseline.
- The alert resolves automatically when the breach is no longer present.
Latency anomalies are independent from availability. A monitor can be up while unusually slow and therefore have a latency alert without an availability alert.
Host metric, mesh, and TLS expiry alerts
An agent monitor defines metric_rules: up to 50 threshold rules over any metric its collector reports, compared in the metric's native unit (*.utilization metrics are ratios, so 90% is 0.9), with optional attribute filters and an optional sustained-for duration that must hold for the whole window before the alert opens. A rule without filters fans out per matching series — one filesystem rule opens one host_metric alert per breaching mountpoint.
Each alert is keyed by its canonical series key (for example system.filesystem.utilization{device=/dev/sda1,mode=rw,mountpoint=/data,type=ext4}) and resolves independently when the series returns within the rule or the rule is removed. Evaluation is freshness-bounded to three monitor intervals (90-second floor), so a dead collector's last stale readings cannot keep metric alerts open — the availability alert covers that outage. Alerts migrated from the retired metric_thresholds fields keep working; their legacy names still render on existing alert records.
A location mesh edge opens a mesh_edge alert after its directional failure threshold. The reverse direction is a different condition. Mesh alerts use tenant default channels.
An HTTP monitor with tls_min_days_valid opens a tls_expiry alert when its most recently observed certificate has fewer remaining validity days than the threshold. The certificate window does not fail the check: the endpoint stays up and the warning is a distinct alert kind, so an aging certificate is distinguishable from an outage. The alert resolves when a renewed certificate is observed or the threshold is removed. A fully expired certificate fails the TLS handshake itself and therefore surfaces as a regular availability alert.
Maintenance windows and snoozes
| Field | Meaning |
|---|---|
title | Required operator-facing title |
description | Optional maintenance context |
starts_at | RFC 3339 start timestamp |
ends_at | RFC 3339 end timestamp, after the start |
monitor_ids | Selected tenant monitors; selecting a group also covers its members for muting |
Maintenance windows are classified as upcoming, active, or past. Checks continue to execute and states continue to change; the alert opening/notification path is muted for covered monitors during the active interval.
A monitor can also be snoozed until an explicit timestamp or for a duration in minutes. Snooze is a concise one-monitor maintenance action, not a pause in data collection.
Dependency-aware alerting
When a downstream availability alert opens, Probara inspects its dependency graph and annotates the alert with the deepest currently down upstream monitor. Ties prefer the upstream condition that became down earlier. The annotation is recomputed every evaluation tick and cleared when no qualifying cause remains; it is always on and always visible on the alert, in notifications ("likely root cause") and in the operator UI.
Whether the annotation also suppresses the downstream page is a policy. It is off by default: enable dependency_suppression_enabled in the workspace notification settings to page root causes only, and override it per monitor with dependency_suppression (inherit, on, off) in the monitor's Alerting section — off keeps a critical monitor paging whatever the workspace says.
- A suppressed downstream alert still opens, still counts on the dashboard, still resolves and still drives incidents and status pages; only its notifications are withheld. The API reports it with
suppression_reason: "dependency", the alert list and dashboard flag it, andGET /api/v1/alerts?suppressed=truelists exactly those alerts. - The root cause's own DOWN and reminder notifications carry an Also affecting section naming the suppressed downstream monitors (
impacted_monitors/impacted_count; the API exposesimpacted_counton the alert), recomputed on every send. - When the upstream recovers but the downstream is still down, the downstream stays quiet for
dependency_suppression_grace_seconds(default 120) so a monitor that recovers one check later never pages. After the grace it pages as a normal DOWN, with escalation-tier delays counted from that moment rather than from when the outage began. - A downstream that recovers while suppressed was never announced, so no recovery notification is sent for it. A downstream that paged before its upstream was detected keeps its recovery notification but stops sending reminders while the upstream explains it.
- Suppression is decided at dispatch, from live state, by the same predicate the API uses to compute
suppression_reason; it is not part ofalert_routing, which describes static routing configuration.
Incidents
| Variable | Values or purpose |
|---|---|
title / summary | Required incident description |
severity | critical, high, medium, or low |
owner | Optional ownership label |
status | investigating, identified, monitoring, or resolved |
source | manual or automatically created |
| Linked resources | Attach or detach alerts and monitors as investigation changes |
Timeline entries can be system events, internal notes, or public updates. Publishing an incident to a status page exposes only the page-relevant subset: the incident and page must share selected linked monitors. Unpublishing removes it from that page without deleting the incident.
- Create an incident manually, or enable automatic creation for supported alert paths.
- Attach the alerts and affected monitors used for internal context.
- Set severity, owner, and lifecycle status as the response progresses.
- Add internal notes for operators and public updates for subscribers.
- Publish to each relevant status page, then unpublish or resolve when appropriate.
AI-assisted incident analysis
When an effective tenant LLM configuration is enabled, an incident analysis request queues asynchronous work. Its result progresses through pending, ready, or failed and can include a summary, probable root cause, contributing factors, recommended actions, confidence, and evidence.
Retired alert-policy API
Legacy /alert-policies endpoints return HTTP 410 Gone. Configure tenant notification defaults, monitor-specific routing, consecutive failure thresholds, agent metric thresholds, and latency-anomaly settings instead.