Change-Driven Alert Suppression in EMS ΒΆ
Design Document Β· EMS Platform Team
π Draft Β |Β π― Scope: PCC Team Alert Triage Β |Β π EMS + EAP Change Agent
Contents ΒΆ
- Background
- System Architecture Overview
- Problem Statement
- Solution Design
- Scope
- Decision Rationale
- Flow Diagram
- EMS Required Changes
- Operator Workflow Change
- Success Metrics
1. Background ΒΆ
During planned maintenance changes (ServiceNow Change Requests), related alerts flood the EMS feed, causing noise for the PCC team. Today there is no automated mechanism to suppress these expected alerts for the duration of the change window.
2. System Architecture Overview ΒΆ
βββββββββββββββββββββββββββββββββββ βββββββ ββββββββββββββββββββββ
β ALERT SOURCES β β β β USERS β
β Grafana / Prometheus AlertMgr β β β β PCC Team β
β Splunk β βββ β EMS β βββ β Service Ops Teams β
β TAP Tests β β β β (Alert triage) β
β EM7 β β β ββββββββββββββββββββββ
β ThousandEyes β βββββββ
β SolarWinds β
βββββββββββββββββββββββββββββββββββ
3. Problem Statement ΒΆ
When a service owner executes a planned change (e.g. a network or infrastructure maintenance), a burst of expected alerts is generated by the upstream monitoring systems and lands in the EMS feed. Triage owners must manually distinguish these expected change-related alerts from genuine incidents, increasing triage time and cognitive load.
There is currently no automated suppression tied to the change lifecycle. The desired behaviour is: when a ServiceNow change enters Implement status, the alerts that are predictably caused by that change are automatically suppressed in EMS for the duration of the change window.
4. Solution Design ΒΆ
4.1 Trigger ΒΆ
EMS subscribes to all ServiceNow change-status events as the single source of truth for suppression triggers β regardless of whether the status was updated via EAP or directly in ServiceNow. When a change transitions to Implement, EMS directly creates a Maintenance Window in code. No external post-step call is needed.
4.2 Maintenance Window Creation ΒΆ
When the Implement event is received, EMS first decides the window mode, then builds the CEL expression accordingly. The mode depends on whether the change type has an explicit change-type β alert-name mapping (see Β§4.3):
- Suppress mode (mapping exists β high confidence) β the window actively suppresses matching alerts. Its CEL is more precise:
customer+deviceplusalert_name β mapped set, so only the alert names this change type is known to produce are caught. - Label-only mode (no mapping β low confidence) β the window does not suppress; it only labels and groups. Its CEL is broader:
customer+deviceonly, since we cannot narrow by alert name.
Label-only is a new Maintenance Window mode
Rather than introducing a separate correlation/enrichment mechanism, label-only is added as an option to the existing Maintenance Window feature: it injects a label and groups matching alerts without changing their status. This keeps the whole flow terminating at a single point β create a Maintenance Window β regardless of confidence.
The window schedule (start_time / end_time) is set from the change's planned start and end dates in both modes.
CEL building method:
- Phase 1: static rule-based build directly from change metadata (e.g.
customer == 'Acme Corp',labels.device_name == 'web-server-01', and in suppress modelabels.alertname in [...]). The CI list in the ticket is expected to already be comprehensive at this point (see note below). - Phase 2 (future): an AI Agent builds the CEL from broader change context, enabling richer and more accurate scope inference in either mode. Like Multi-Tier dependency traversal for CI discovery from topology.
4.3 Alert Handling: Suppress vs. Label-only ΒΆ
Upstream: CI coverage at ticket creation time
Topology-based CI expansion (discovering VMs running on an affected host, peer/cluster members not explicitly listed, etc.) should happen when the change ticket is being created, not at suppression time. The affected CI list in ServiceNow should already be complete and accurate by the time the ticket reaches Implement status.
A CEL match by customer + device alone is a fairly broad signal β it means "an alert on a device touched by this change", not necessarily "an alert caused by this change". Suppressing every such alert risks over-suppression: hiding a genuine, unrelated incident that happens to fire on the same device during the change window. To guard against this, EMS chooses the mode based on confidence:
Suppress mode (high confidence). Only when the change type has an explicit change-type β alert-name mapping β i.e. we know which specific alert names this kind of change is expected to produce β does EMS build a suppressing window whose CEL includes that alert-name set. A matching alert is marked with status = SUPPRESSED, tagged with the change_number label, grouped under the change, and removed from the operator's default view.
Label-only mode (low confidence). When no such mapping exists, EMS builds a label-only window scoped to customer + device only. A matching alert is processed normally (stays visible for triage), but is tagged with a suspected_change_number label and grouped under the change. This gives the operator the context "a change is running on this device, this alert may be related" without risking that a real incident is silently hidden.
Label naming
change_numberandsuspected_change_numberare deliberately distinct keys. The former asserts the alert is change-caused (and was suppressed); the latter only flags a suspected correlation (device + time overlap) with no suppression. Both carry the sameCHGxxxxvalue, so a single query can still retrieve everything related to a change while preserving the confidence distinction.
Alerts that do not match any active window's CEL are processed normally.
4.4 Early Window Termination ΒΆ
When an operator sets a change to Complete, Cancel, or Review in ServiceNow before its scheduled end time, EMS detects the status-change event via the same subscription and deactivates the corresponding Maintenance Window by setting end_time = now(). All subsequent alerts then resume normal processing.
4.5 Phase 2 β AI-assisted CEL Build ΒΆ
In Phase 2, the static CEL build step is replaced by an AI Agent that derives the CEL expression from broader change context (ticket description, CMDB relationships, historical patterns, etc.). This enables more accurate and comprehensive suppression scope without requiring operators to manually maintain an exhaustive affected-CI list. Phase 2 is out of scope for the current implementation.
5. Scope ΒΆ
In scope
This suppression mechanism serves the PCC team alert triage workflow in EMS. It suppresses alerts within the EMS feed for the duration of a planned change window.
Out of scope
- Suppression in Control Hub or any other downstream alert consumer. Each system's suppression remains that system's own responsibility.
- A unified / cross-team "enterprise suppression platform." This design deliberately solves the current PCC pain point without trying to build a big, all-encompassing solution that would take significantly longer to deliver and get buy-in for.
6. Decision Rationale ΒΆ
Why not suppress upstream (Grafana / Splunk)? ΒΆ
Silencing rules in Grafana AlertManager or Splunk requires per-rule action, with no centralised view of what is silenced and why. Mapping a change's affected devices to the correct Grafana/Splunk alert rules is operationally fragile and does not scale as the number of rules and changes grows. It also leaves the noise problem unsolved for any additional alert sources that onboard to EMS in the future.
Why not add a dedicated filter/relay layer between upstream and EMS? ΒΆ
Inserting a new filtering layer (similar to an "AlertHub") would likely face objection from the LMA team, who own the upstream pipeline. It would also introduce a new service to maintain, increase end-to-end latency, and create a dependency on a separate component that is outside the EMS team's operational boundary.
Why EMS Maintenance Windows? ΒΆ
EMS already has a Maintenance Window feature (backed by CEL evaluation per incoming alert) that is purpose-built for exactly this use case. Extending it with a label-only mode (Β§8.2) lets both the high-confidence suppress path and the low-confidence label-only path terminate at the same point, so all logic stays within EMS where the PCC team already operates, and avoids introducing any new service or cross-team dependency.
7. Flow Diagram ΒΆ
flowchart TD
%% ββ Upstream: change creation via EAP (separate flow) ββββββββββββββββ
subgraph CREATION ["π§ Change Creation (via EAP Change Agent)"]
direction TB
CREATE_USER(["π€ Operator creates
Change Ticket in EAP"])
TOPO_AGENT["AI Agent queries
CI / Device Topology"]
TOPO_VMS["Discover: VMs / workloads
running on affected host"]
TOPO_PEERS["Discover: peer / cluster members
not explicitly listed"]
FILL_CI["Populate Affected CI list
in ServiceNow ticket"]
CREATE_USER --> TOPO_AGENT
TOPO_AGENT --> TOPO_VMS
TOPO_AGENT --> TOPO_PEERS
TOPO_VMS --> FILL_CI
TOPO_PEERS --> FILL_CI
end
%% ββ Main suppression flow ββββββββββββββββββββββββββββββββββββββββββββ
SN_USER(["π€ Operator sets Change to
'Implement' in ServiceNow"])
EMS_SUB["EMS subscribes to all
ServiceNow change-status events
(single source of truth)"]
SN_USER -- "ServiceNow\nstatus event" --> EMS_SUB
EMS_SUB --> MODE{"Change type has explicit
change-type β alert-name
mapping?"}
%% ββ Suppress mode (high confidence) ββββββββββββββββββββββββββββββββββ
MODE -- "Yes\n(high confidence)" --> MW_S["Create Maintenance Window
mode = SUPPRESS"]
MW_S --> CEL_S["Build CEL
customer + device
+ alert_name β mapped set"]
%% ββ Label-only mode (low confidence) βββββββββββββββββββββββββββββββββ
MODE -- "No\n(avoid over-suppression)" --> MW_L["Create Maintenance Window
mode = LABEL-ONLY"]
MW_L --> CEL_L["Build CEL
customer + device"]
subgraph PHASE2["β‘ Phase 2 β AI-assisted CEL Build (future)"]
direction TB
AI_CEL_BUILD["AI Agent builds CEL
from broader change context
For example: Multi-Tier
dependency traversal for
CI discovery from topology"]
end
CEL_S -. "Phase 2 alt" .-> AI_CEL_BUILD
CEL_L -. "Phase 2 alt" .-> AI_CEL_BUILD
CEL_S --> SCHED["Set Window Schedule
from Change Schedule"]
CEL_L --> SCHED
SCHED --> WIN
WIN{{"Maintenance Window
Active in EMS"}}
WIN --> MATCH{"Incoming alert
matches window CEL?"}
MATCH -- No --> NORMAL["Alert processed normally
(stored, triaged, etc.)"]
MATCH -- "Yes
(suppress-mode window)" --> SUPPRESSED["Alert enters EMS
with status = SUPPRESSED
+ change_number label injected
+ grouped by change
β Removed from default view
β Audit trail written"]
MATCH -- "Yes
(label-only window)" --> LABELED["Alert processed normally
(NOT suppressed)
+ suspected_change_number label injected
+ grouped by change
β Stays visible for triage
β Audit trail written"]
%% ββ Early termination ββββββββββββββββββββββββββββββββββββββββββββββββ
CLOSE_USER(["π€ Operator sets Change to
'Complete / Cancel / Review'
in ServiceNow"])
CLOSE_EMS["EMS subscription detects
status change event"]
CLOSE_ACTION["Deactivate Maintenance Window
set end_time = now()"]
CLOSE_USER -- "ServiceNow\nstatus event" --> CLOSE_EMS
CLOSE_EMS --> CLOSE_ACTION
CLOSE_ACTION --> MW_END(["Window terminated early
Alerts resume
normal processing"])
8. EMS Required Changes ΒΆ
| # | Change | Description | Priority |
|---|---|---|---|
| 1 | Subscribe to ServiceNow change-status events | EMS subscribes to ServiceNow change-status events as the single source of truth for all suppression triggers. On detecting a transition to Implement, EMS directly creates the corresponding Maintenance Window in code β no external post-step call is required. The same subscription also drives early termination: when a change transitions to Complete / Cancel / Review, EMS automatically deactivates the Maintenance Window by setting end_time = now(). | P1 |
| 2 | New Maintenance Window "label-only" mode | Extend the existing Maintenance Window feature with a label-only mode that injects a label and groups matching alerts without changing their status to SUPPRESSED. (Today the window either suppresses or drops matching alerts; neither fits the low-confidence case.) This lets the entire flow terminate at a single point β create a Maintenance Window β for both confidence levels. | P1 |
| 3 | Change-to-CEL translation logic | EMS must be able to parse a ServiceNow change record and derive a valid CEL expression for the Maintenance Window, scoped to the chosen mode. Suppress mode: customer + device + alert_name β mapped set. Label-only mode: customer + device only. Phase 1: rule-based extraction from change metadata. Phase 2 (future): delegate CEL construction to an AI Agent that reads the full change context. Also covers modifying the window on early termination. | P1 |
| 4 | Change-type β alert-name mapping & mode selection | Maintain a mapping of change type β expected alert names. Before building the CEL, EMS uses it to pick the mode: suppress mode when the change type has an explicit mapping (high confidence), label-only mode otherwise (avoids over-suppression by not hiding potentially unrelated incidents). The mapping should be operator-maintainable and, in Phase 2, extendable via AI-generated rules. | P1 |
| 5 | Add change labels to alert body | Inject a change label into matching alerts' enrichment: change_number (e.g. CHG0012345) for suppressed alerts in suppress mode, and suspected_change_number for label-only alerts. Both enable building a Change preset, querying alerts by change for post-change review, and driving per-change metrics (see Β§10). The distinct keys preserve the confirmed-vs-suspected confidence distinction. | P1 |
9. Operator Workflow Change ΒΆ
Before (today) ΒΆ
Operators manually add a ticket_number=CHGxxxx label to alerts they believe are change-related, then manually group those alerts into a Group Alert.
After (with this solution) ΒΆ
EMS auto-injects a change label on matching alerts and automatically groups them under the corresponding change's Group Alert. Operators no longer need to do this manually for alerts within scope.
- In suppress mode, alerts get the
change_numberlabel, are set to Suppressed, and are removed from the operator's default view β reducing noise and cognitive load during triage. - In label-only mode, alerts get the
suspected_change_numberlabel and are grouped, but stay visible so a genuine incident is never silently hidden.
Manual fallback for missed alerts ΒΆ
When an operator identifies an alert that was not automatically suppressed but is clearly change-related, they can:
- Manually add the
change_number=CHGxxxxlabel to the alert. - Batch-update the alert status to Suppressed.
- Add the alert to the corresponding change Group Alert.
Why this matters ΒΆ
Every manually tagged alert is a signal that the auto-suppression scope missed something. Aggregating manual and automatic suppressions together lets the team:
- Identify coverage gaps and iterate on CEL rules β or generate AI skills to close them.
- Measure total suppression volume (auto + manual) and the auto hit rate.
- Quantify ops effort saved, building the business case for continued investment.
10. Success Metrics ΒΆ
All metrics below are derivable from the change_number / suspected_change_number labels automatically injected on matching alerts (Β§8.5) plus the manual-fallback tagging described in Β§9.
Ops Effort Saved ΒΆ
- Estimated triage hours eliminated β suppressed alert count Γ average time an operator would spend triaging a change-related alert. This is the headline ROI figure to present to stakeholders.
- Manual labeling toil removed β volume of alerts that would previously have required a human to add
ticket_number=CHGxxxxand group manually, now handled automatically.
CEL Coverage Accuracy ΒΆ
- Auto-suppression coverage rate β auto-suppressed alerts Γ· (auto-suppressed + manually-tagged missed alerts). Tracks how well the CEL rules capture the actual change scope. A declining rate signals rule drift; a persistently low rate for a change type justifies building a Phase 2 AI skill for that category.
- Mapping maturity / promotion candidates β
suspected_change_numberalerts whose alert names recur consistently for a given change type are candidates to promote into the change-type β alert-name mapping, converting label-only handling into full suppression over time. The volume of suspected-but-not-suppressed alerts is the backlog that drives mapping expansion.
Team Performance During Change Windows ΒΆ
- MTTA / MTTR for genuine incidents β mean time to acknowledge and resolve alerts that are not change-related, measured during active change windows before vs. after suppression is enabled. Fewer distractions from noise should produce a measurable drop.
- Change noise ratio β change-related alerts as a percentage of all alerts fired during a window. Quantifies the scale of the problem and the magnitude of improvement.
Auditability & Compliance ΒΆ
- Post-change review completeness β after a change closes, every alert suppressed during the window is queryable by change number. Supports CAB reviews, SLA reporting, and incident retrospectives without manual reconstruction.
Implementation note
Add
change_numberandsuspected_change_numberas filterable labels in EMS. The existing facet / preset system can then expose a Change preset automatically once the labels are present.