Skip to main content

Notification filters overview

Notification filters control which alert events are delivered to a notification subscription.

Filters use JSON Logic. Each filter is evaluated against the alert event, derived event statistics, and selected active alert state.

What filters are for

Use filters when a subscription should receive only a subset of alert events, for example:

  • only high-impact events
  • only events affecting specific nodes or metric types
  • only events where a value increased compared to the previous event
  • only events where the current alert has an active red-or-worse metric
  • only events where an active anomaly exists for a specific node, metric, label, or system

Supported inputs

The filter engine supports these variable roots:

RootDescription
event.*The current notification event payload. For alert events, event.changes[] contains only the changes from the current event.
computed.*Derived values used for matching, including current values, previous values, presence arrays, and historical maxima when available.
alerts.current.*Active state of the current alert at the time referenced by the event. Loaded only when the filter references alerts.current.

anomaly.* variables are allowed only inside the predicate argument of anomalyExists.

Computed values

At a high level, computed includes:

  • aggregate current and previous values for active metrics, active nodes, and impact
  • historical max values such as max_8h, max_24h, and max_lifetime
  • presence arrays for nodes, metric types, and node-metric pairs
  • severity values per node-metric pair

Example paths:

PathDescription
computed.impact.currentCurrent event impact rank.
computed.impact.prevPrevious event impact rank when available.
computed.impact.max_24hHighest impact rank seen in the last 24 hours.
computed.activeMetrics.currentCurrent active metric count.
computed.activeNodes.currentCurrent active node count.
computed.nodesArray.presentNode IDs present in the event-derived context.
computed.statTypesArray.presentMetric type IDs present in the event-derived context.

Current alert state

Use alerts.current when the filter needs the full active state of the current alert, not just the event delta in event.changes[].

alerts.current is evaluated at the time referenced by the event. It is null when no active state is available for the current alert at that time.

PathTypeDescription
alerts.current.idstringCurrent alert ID.
alerts.current.activebooleanAlways true when alerts.current is loaded.
alerts.current.activeNodesnumberNumber of active nodes on the current alert.
alerts.current.activeMetricsnumberNumber of active metrics on the current alert.
alerts.current.maxSeverity.namestringHighest active severity name on the current alert.
alerts.current.maxSeverity.ranknumberHighest active severity rank on the current alert.
alerts.current.metricsarrayActive metric rows for the current alert. Use array operators such as some to inspect individual metrics.

Inside some, all, none, filter, or map over alerts.current.metrics, use rootless metric paths.

Metric pathDescription
alertIdAlert ID.
nodeIdNode ID.
nodeNameNode name, or null when unavailable.
nodeTypeIdNode type ID, or null when unavailable.
nodeLabelsNode labels.
statTypeIdMetric type ID.
statTypeNameMetric type name, or null when unavailable.
statTypeLabelsMetric type labels.
systemIdSystem ID, or null when unavailable.
systemNameSystem name, or null when unavailable.
severity.nameSeverity name.
severity.rankSeverity rank.
typeAnomaly type, such as deviation or missing_data, or null.
score.adjustedAdjusted anomaly score.
score.contributionContribution score.
learningStatusLearning status value.
closestBaselineDeviationClosest baseline deviation, or null.
closestBaselineDeviationAbsPeakAbsolute peak deviation, or null.
closestBaselineDeviationAbsLevelAbsolute level deviation, or null.

Cross-alert anomaly checks

Use anomalyExists to check whether at least one active anomaly matches a selector and optional predicate at the time referenced by the event. It searches all active anomalies visible to the subscription, including anomalies on other alerts.

{
"and": [
{
"some": [
{ "var": "alerts.current.metrics" },
{ "==": [{ "var": "nodeId" }, 123] }
]
},
{
"anomalyExists": [
{
"system": { "name": "Production line A" }
},
{ "!=": [{ "var": "anomaly.nodeId" }, 123] }
]
}
]
}

This example matches when node 123 is active on the current alert and another node in Production line A is anomalous at the same referenced time.

The first argument is a static selector object. Selector values must be constants, not variables.

Selector pathTypeDescription
node.idnumberMatch a node by ID.
node.namestringMatch a node by name.
node.typeIdstringMatch a node by type ID.
node.labels.anystring[]Match nodes with at least one of these labels.
node.labels.allstring[]Match nodes with all of these labels.
statType.idstringMatch a metric type by ID.
statType.namestringMatch a metric type by name.
statType.labels.anystring[]Match metric types with at least one of these labels.
statType.labels.allstring[]Match metric types with all of these labels.
system.idnumberMatch nodes in a system by system ID.
system.namestringMatch nodes in a system by system name.

The second argument is optional. If omitted, the predicate is treated as true.

Supported predicate operators:

  • and, or, !
  • ==, !=, >, >=, <, <=
  • in with one supported anomaly.* variable and one constant array

Supported predicate variables:

VariableDescription
anomaly.alertIdAlert ID.
anomaly.nodeIdNode ID.
anomaly.statTypeIdMetric type ID.
anomaly.severity.nameSeverity name.
anomaly.severity.rankSeverity rank.
anomaly.typeAnomaly type.
anomaly.score.adjustedAdjusted anomaly score.
anomaly.score.contributionContribution score.
anomaly.learningStatusLearning status value.
anomaly.closestBaselineDeviationClosest baseline deviation.
anomaly.closestBaselineDeviationAbsPeakAbsolute peak deviation.
anomaly.closestBaselineDeviationAbsLevelAbsolute level deviation.

Topology fields such as node name, node labels, system name, metric type name, and metric type labels must be expressed in the selector, not in the predicate.

Example filters

Filter by impact

{
">=": [{ "var": "computed.impact.current" }, 3]
}

Filter by 24-hour peak impact

{
">=": [{ "var": "computed.impact.max_24h" }, 3]
}

Filter by change compared to previous event

{
">": [{ "var": "computed.activeMetrics.current" }, { "var": "computed.activeMetrics.prev" }]
}

Filter by affected node

{
"or": [
{
"in": [101, { "var": "computed.nodesArray.present" }]
},
{
"in": [205, { "var": "computed.nodesArray.present" }]
}
]
}

Filter by current alert severity

{
">=": [{ "var": "alerts.current.maxSeverity.rank" }, 4]
}

Filter by an active metric on the current alert

{
"some": [
{ "var": "alerts.current.metrics" },
{
"and": [
{ "==": [{ "var": "nodeId" }, 101] },
{ "==": [{ "var": "statTypeId" }, "temperature"] },
{ ">=": [{ "var": "severity.rank" }, 4] }
]
}
]
}

Filter by anomaly anywhere

{
"anomalyExists": [
{
"node": { "id": 999 }
}
]
}

Filter by node label and deviation

{
"anomalyExists": [
{
"node": {
"labels": { "any": ["critical"] }
}
},
{
">": [{ "var": "anomaly.closestBaselineDeviation" }, 1.0]
}
]
}

Combine multiple conditions

{
"and": [
{ ">=": [{ "var": "computed.impact.current" }, 3] },
{
"or": [
{ "in": [101, { "var": "computed.nodesArray.present" }] },
{ "in": [205, { "var": "computed.nodesArray.present" }] }
]
},
{
"or": [
{ ">": [{ "var": "computed.activeMetrics.current" }, { "var": "computed.activeMetrics.prev" }] },
{ ">=": [{ "var": "alerts.current.maxSeverity.rank" }, 4] }
]
}
]
}

This example matches events that:

  • have current impact >= 3
  • affect node 101 or 205
  • and either show more active metrics than the previous event or have a current alert severity of red or worse

Testing filters

Use Test notification filter to evaluate a filter against an event before saving it to a subscription.

Notes

  • Invalid filters are rejected when a subscription is created or updated.
  • event.changes[] is the current event delta. Use alerts.current.metrics[] when the filter needs the full active state of the current alert.
  • alerts.current and anomalyExists use the time referenced by the event.
  • Historical computed max values depend on notification stats collected during real execution.