Skip to main content

Use incident fields in rules

Every incident carries a title and a block of details, and it also carries five labels that the sending tool attaches to the alert: its source, tenant, component, type and external ID. You can use these labels in your rules. A routing rule can send every alert for one customer to the team that owns that customer, a parser can store the part of a component name you care about, a grouping strategy can group by tenant, and a notification condition can restrict a channel to one customer.

This page covers the two functions that read these labels, where each one is available, and what happens when an alert does not carry a label.

The five incident fields​

FieldWhat it holds
sourceThe tool that sent the alert, for example New Relic.
tenantThe customer or account the alert belongs to.
componentThe part of the system the alert came from, for example a host.
typeThe kind of alert.
external_idThe identifier the sending tool gave the alert.

Field names are not case-sensitive, and spaces around the name are ignored. These five are the only labels the functions accept. An alert posted through the Oppex API or the generic webhook can carry all five. Other sources send a subset: most send a source and an external ID, and a tenant comes only from sources that have the concept, such as the generic webhook, Google Cloud Monitoring, Cloudflare and OpenSearch. A field the sender did not provide is empty on the incident.

The two functions​

FunctionWhat it does
payload_matches(field, pattern)Is true when the field matches the pattern.
extract_from_payload(field, /regex/)Keeps the part of the field that sits inside the parentheses of the regular expression.

You split the arguments at the first comma, so a comma inside the pattern is safe. You join functions with &&& (and) and ||| (or), write ! directly in front of a function to negate it, and group with ((( and ))). ! is applied first, then &&&, then |||.

Where you can use each function depends on the feature:

Wherepayload_matchesextract_from_payloadThe pattern is
Service Routing ruleYesNoPlain text, not case-sensitive. The field only has to contain it.
Workspace parserYes, as the conditionYes, as the extract ruleA regular expression between slashes.
Algorithmic groupingYes, as the match expressionYes, as an attributeA regular expression between slashes.
Notification conditionNo. The five fields are available by name instead.NoSet by the condition functions.

Regular expressions are case-sensitive. Start one with (?i) to ignore case.

Route incidents to a service by tenant​

A routing rule decides which service an incident lands on when the sender did not name one.

  1. Open Settings, then your workspace, then Service Routing.
  2. Click Add Rule.
  3. In step 1 · Match, next to Look in, select Expression.
  4. In Custom Expression, type payload_matches(. Oppex lists the five fields. Select one.
  5. Complete the expression, for example payload_matches(tenant, redbull) &&& !payload_matches(type, test). Wait for Expression is valid to appear.
  6. Click Next, choose where matching incidents go, click Next, and then click Save.

The Add Routing Rule dialog on step 1 with Expression selected. The user has typed payload_matches( and a list offers the fields source, tenant, component, type and external_id, each with a short description.

The same dialog with the expression payload_matches(tenant, redbull) &&& !payload_matches(type, test) typed in. The message under the box reads Expression is valid, and the and, or and not chips sit below it.

The tenant and type values below show how that expression behaves.

TenantTypeRule matchesWhy
RedBull-RacingalertYesThe tenant contains redbull, ignoring case, and the type does not contain test.
redbullload-testNoThe type contains test, and the expression excludes it.
MercedesalertNoThe tenant does not contain redbull.
Not sentalertNoAn empty tenant matches nothing.
Oppex rejects a mistyped function when you save

If your text calls payload_matches with a field name Oppex does not know, or with no pattern, Oppex refuses to save the rule and shows the reason, for example payload_matches: unknown field 'colour'. Allowed fields: source, tenant, component, type, external_id. Without this check, the text would be saved as a plain title pattern and match unrelated incidents.

Fill a variable from an incident field​

A workspace parser reads a value from each new incident and stores it in a workspace variable. Use payload_matches as the condition and extract_from_payload to pick the value.

  1. Open Settings, then your workspace, then Parsers.
  2. Click Write a rule by hand.
  3. Enter a Name and choose the Linked variable the parser fills.
  4. In Condition, enter payload_matches(tenant, /^redbull/).
  5. In Extract regex, enter extract_from_payload(component, /^(\w+)-/).
  6. Set Run order, choose whether to fill past incidents, and click Add parser.

The Add parser panel filled in. The linked variable is race_team, the condition reads payload_matches(tenant, /^redbull/), and the extract regex reads extract_from_payload(component, /^(\w+)-/). Both boxes show Valid.

The part of the field inside the parentheses becomes the value. For an incident whose tenant is redbull-racing and whose component is pit-wall-api, the condition matches, and the extract rule stores pit, because (\w+) captures the text before the first hyphen. An incident whose tenant is RedBull-Racing does not match, because the condition is case-sensitive.

A parser rule that does not match stores nothing

When the condition is false, or the field is empty, the parser stores no value for that incident, and any later parser for the same variable gets its turn.

Group incidents by an incident field​

An algorithmic grouping strategy uses the match expression as its gate and an attribute to build the group name.

  1. Open the service, then its Algorithmic Grouping page.
  2. Click Add Strategy.
  3. Enter a Strategy Name.
  4. In Match Expression, enter payload_matches(tenant, /^redbull$/).
  5. Click Add Attribute, name it, and keep Should match.
  6. In Extraction Expression, enter extract_from_payload(component, /^(\w+)-/).
  7. Click Create Strategy.

The Add Strategy panel with the match expression payload_matches(tenant, /^redbull$/) and one attribute named team whose extraction expression is extract_from_payload(component, /^(\w+)-/). The match expression shows Valid.

With this strategy, an incident whose tenant is exactly redbull and whose component is pit-wall-api joins a group named pit. A later incident with the component pit-lane-timing also produces pit, so it attaches to the open incident that already carries that group. An incident for any other tenant is not affected by the strategy.

Algorithmic grouping must be switched on for your account

If the Algorithmic Grouping page is not available, ask your account administrator to enable it.

Notify only for one customer​

A notification condition is a saved test that a notification route can use, so that the route sends only for incidents the test accepts. In a condition, the five fields are available by name with the prefix incident.: incident.source, incident.tenant, incident.component, incident.type and incident.external_id. You test them with the condition functions, such as equals, contains, starts_with, matches, in and exists.

  1. Open Settings, then your workspace, then Conditions.
  2. Click Add condition.
  3. Enter a Name.
  4. Click Insert field and select a field, or type the name.
  5. Enter an expression, for example equals(incident.tenant, "redbull") &&& matches(incident.component, /^pit-wall/).
  6. When Valid expression appears, click Add condition.
  7. Open a service, add a notification route, and choose the condition in the route's Condition list.

The Add condition panel with the Insert field list open. It shows incident.title, incident.service, incident.source, incident.tenant and incident.component, each marked as a built-in string field with a short description.

The panel also offers sample values, so you can check an expression before you save it.

In a condition, a negated test on an empty field is true

!equals(incident.tenant, "redbull") is true for an incident that carries no tenant, because the tenant is simply not redbull. This differs from !payload_matches in routing, parsers and grouping, where a negated test on an empty field is false. Add exists(incident.tenant) to the condition if you want to exclude incidents with no tenant.

Pick a field without typing it​

Every expression editor that accepts payload_matches or extract_from_payload helps you write it.

  • Type the function name and an opening parenthesis. Oppex lists the five fields with a short description of each. Press Enter or click a field to insert it.
  • Under the editor, the and, or and not chips write the operator symbols at the caret. Hover a chip to read what it does.
  • Select How it works to see plain-language examples and add one to the editor.

When an alert does not send a field​

A field the sender did not provide, or sent blank, is empty. In routing rules, parsers and grouping:

  • payload_matches on an empty field is false.
  • extract_from_payload on an empty field stores nothing.
  • !payload_matches on an empty field is also false. A rule such as !payload_matches(tenant, mercedes) therefore does not match alerts that carry no tenant, which keeps a rule that suppresses incidents from silencing every alert whose sender never sends a tenant.

Notification conditions behave differently for negated tests, as the warning in the previous section describes.

FAQ

Is matching case-sensitive, and is the pattern text or a regular expression?

In Service Routing, the pattern is plain text, it is not case-sensitive, and the field only has to contain it. In parsers and grouping, the pattern is a regular expression between slashes and it is case-sensitive, so start it with (?i) to ignore case. In notification conditions, equals is exact and case-sensitive, and matches takes a regular expression.

Why can I not use the group or the severity of an incident?

Oppex accepts only the five fields in this page. An incident's group and severity can change after the incident arrives, so a rule on them could behave differently when it is applied to a new incident and when it is applied to an older one. Use title_matches to test the title.

Why was my rule rejected when I saved it?

Oppex checks the expression before it saves. The most common causes are a field name that is not one of the five, a missing pattern, and a regular expression that is not valid. The message under the editor names the problem.

Is there a limit on how long a field value can be?

Yes. Source, tenant, component and type can each be up to 255 characters, and the external ID can be up to 128. Oppex rejects an incident with a longer value and the response names the field, for example Tenant must not exceed 255 characters.

What happens if my alert source never sends a field?

The rule does not fail, but it never matches. A tool that does not send a tenant never satisfies payload_matches(tenant, ...), so check which fields your source sends before you rely on one.

In this article

FAQ

Is matching case-sensitive, and is the pattern text or a regular expression?

In Service Routing, the pattern is plain text, it is not case-sensitive, and the field only has to contain it. In parsers and grouping, the pattern is a regular expression between slashes and it is case-sensitive, so start it with (?i) to ignore case. In notification conditions, equals is exact and case-sensitive, and matches takes a regular expression.

Why can I not use the group or the severity of an incident?

Oppex accepts only the five fields in this page. An incident's group and severity can change after the incident arrives, so a rule on them could behave differently when it is applied to a new incident and when it is applied to an older one. Use title_matches to test the title.

Why was my rule rejected when I saved it?

Oppex checks the expression before it saves. The most common causes are a field name that is not one of the five, a missing pattern, and a regular expression that is not valid. The message under the editor names the problem.

Is there a limit on how long a field value can be?

Yes. Source, tenant, component and type can each be up to 255 characters, and the external ID can be up to 128. Oppex rejects an incident with a longer value and the response names the field, for example Tenant must not exceed 255 characters.

What happens if my alert source never sends a field?

The rule does not fail, but it never matches. A tool that does not send a tenant never satisfies payload_matches(tenant, ...), so check which fields your source sends before you rely on one.