Event Management – Correlation Behavior After 7 Days

Pranita Bahugun
Giga Guru

Hello all,

We have a requirement to update Event Management integration so that events should no longer correlate to an existing alert once 7 days have passed since the alert was opened. Instead, a new alert should be created, the previous alert should be closed, and the related incident ticket should be updated with a hyperlink to the newly created alert.

Has anyone implemented this type of correlation logic before? Specifically:

  • Which Event Management property or configuration should be used to enforce the 7‑day threshold?

  • How can we automatically close the old alert and update the incident with a link to the new alert?

  • Are there recommended best practices or scripts for handling this scenario?

Any guidance or examples from your implementations would be greatly appreciated.

4 REPLIES 4

Naveen20
ServiceNow Employee

Properties to Set

  • evt_mgmt.active_interval1 (1 second) — ensures a new alert is created immediately after the old one is closed, rather than reopening it
  • evt_mgmt.alert_reopens_incidentCreate new incident — so the new alert gets its own incident
  • evt_mgmt.alert_auto_close_interval → leave at 168 (default 7 days) for idle alerts

Custom Scheduled Job 

Since OOB properties only handle idle/closed alerts, create a scheduled job that runs hourly to force-close any open alert older than 7 days based on sys_created_on:

 
 
javascript
var alert = new GlideRecord('em_alert');
alert.addEncodedQuery('stateNOT IN3,4^sys_created_on<javascript&colon;gs.daysAgoStart(7)');
alert.query();
while (alert.next()) {
    // Capture incident ref before closing
    var incidentId = alert.getValue('incident');
    
    alert.setValue('state', '4'); // Closed
    alert.work_notes = 'Auto-closed: exceeded 7-day correlation threshold.';
    alert.update();
    
    // Update incident with note (new alert link added via BR below)
    if (incidentId) {
        var inc = new GlideRecord('incident');
        if (inc.get(incidentId)) {
            inc.work_notes = 'Alert ' + alert.getDisplayValue('number') + 
                ' closed after 7-day threshold. New alert will be linked upon creation.';
            inc.update();
        }
    }
}

Business Rule on em_alert (after insert):

When the next event creates a new alert, link it back to the old incident

 
javascript
var oldAlert = new GlideRecord('em_alert');
oldAlert.addQuery('message_key', current.getValue('message_key'));
oldAlert.addQuery('state', '4');
oldAlert.addQuery('sys_id', '!=', current.getUniqueValue());
oldAlert.orderByDesc('sys_updated_on');
oldAlert.setLimit(1);
oldAlert.query();
if (oldAlert.next() && oldAlert.getValue('incident')) {
    var inc = new GlideRecord('incident');
    if (inc.get(oldAlert.getValue('incident'))) {
        inc.work_notes = 'New alert created: [code]<a href="em_alert.do?sys_id=' +
            current.getUniqueValue() + '">' + current.getDisplayValue('number') + '</a>[/code]';
        inc.update();
    }
}

OOB properties handle the "after close" behavior, the scheduled job enforces the 7-day hard ceiling on open alerts, and the business rule stitches the incident trail together. Test in sub-prod first — especially the timing between the scheduled job closing the alert and the next event arriving.

Hi @Naveen20 ,

Thankyou so much for the reply, i wanted to check if the below requirement is possible achieving:

In Event Management,

I have a use case where an alert (Alert 1) has multiple events attached (Event 1, Event 2, Event 3). After 7 days, Alert 1 is still open.

If and only if a new event (Event 4) arrives after the 7‑day threshold, I don’t want it to correlate to Alert 1 (open). Instead, the system should:

  • Create a new alert (Alert 2) and then,

  • Close Alert 1.

  • Close the linked incident (Incident 1).

  • Update Incident 1’s work notes with a hyperlink to Alert 2.

  • Mark both Alert 1 and Incident 1 as closed due to “threshold crossed.”

Please let me know if this scenario is doable ?

 

Thanks,

Pranita Bahuguni

@Pranita Bahugun 

Yes, this is doable, but it's not OOB behavior — you'll need a custom implementation. ServiceNow Event Management's default correlation engine doesn't have a built-in "age threshold" that prevents new events from binding to an existing alert. Here's how to build it:

The Core Mechanism — Custom Alert Correlation Rule + Business Rule

Step 1: Intercept the correlation before it happens

The key interception point is a Before Business Rule on the em_event table (or a custom Alert Correlation Rule). When a new event arrives and the connector/correlation engine tries to match it to an existing alert, you need to check the alert's age:

 
 
javascript
(function executeRule(current, previous) {
    // 'current' is the incoming event (em_event)
    // Find the alert it would correlate to
    var alert = new GlideRecord('em_alert');
    alert.addQuery('source', current.source);
    alert.addQuery('node', current.node);
    alert.addQuery('type', current.type);
    alert.addActiveQuery(); // only open alerts
    alert.orderByDesc('sys_created_on');
    alert.setLimit(1);
    alert.query();

    if (alert.next()) {
        var createdOn = new GlideDateTime(alert.getValue('sys_created_on'));
        var now = new GlideDateTime();
        var diffDays = gs.dateDiff(createdOn.toString(), now.toString(), true);
        var daysDiff = parseInt(diffDays) / 86400; // convert seconds to days

        if (daysDiff >= 7) {
            // THRESHOLD CROSSED — prevent correlation to old alert
            // Force new alert creation by clearing the correlation key
            // or setting a unique differentiator
            current.setValue('alert', ''); // detach from old alert
            current.setValue('message_key', 
                current.getValue('message_key') + '_threshold_' + now.getNumericValue());
            
            // Store old alert sys_id for post-processing
            current.work_notes = alert.sys_id.toString();
        }
    }
})(current, previous);

The trick is modifying the message_key (or the correlation fields) so the event engine sees it as a new, uncorrelated event and creates Alert 2 instead of binding to Alert 1.

Step 2: Post-creation cleanup — Close Alert 1, close Incident 1, cross-link

Use an After Business Rule on em_alert (on insert) or a Flow Designer flow triggered when a new alert is created with the threshold marker:

 
 
javascript
(function executeRule(current, previous) {
    // Check if this new alert was created from a threshold-crossed event
    var event = new GlideRecord('em_event');
    event.addQuery('alert', current.sys_id);
    event.orderByDesc('sys_created_on');
    event.setLimit(1);
    event.query();

    if (event.next() && event.work_notes) {
        var oldAlertId = event.work_notes; // sys_id of Alert 1
        
        // 1. Close Alert 1
        var oldAlert = new GlideRecord('em_alert');
        if (oldAlert.get(oldAlertId)) {
            oldAlert.setValue('state', 'Closed'); // or appropriate close state
            oldAlert.setValue('close_notes', 
                'Auto-closed: Correlation threshold (7 days) crossed. ' +
                'Successor alert: ' + current.number);
            oldAlert.update();

            // 2. Find and close linked Incident 1
            var incident = new GlideRecord('incident');
            incident.addQuery('sys_id', oldAlert.getValue('incident'));
            incident.query();

            if (incident.next()) {
                // Add work note with hyperlink to new alert
                var alertLink = '[code]<a href="/em_alert.do?sys_id=' + 
                    current.sys_id + '">' + current.number + '</a>[/code]';
                incident.work_notes = 'Alert correlation threshold crossed (7 days). ' +
                    'Original alert closed. New alert created: ' + alertLink;
                incident.setValue('state', 7); // Closed
                incident.setValue('close_code', 'Closed/Resolved by Caller');
                incident.setValue('close_notes', 
                    'Threshold crossed — successor alert ' + current.number);
                incident.update();
            }
        }
    }
})(current, previous);

Step 3 (Optional but recommended): Make the threshold configurable

Create a system property evt_mgmt.alert.correlation.max_age_days set to 7. Reference it in your BR instead of hardcoding:

 
 
javascript
var maxDays = parseInt(gs.getProperty('evt_mgmt.alert.correlation.max_age_days', '7'));
if (daysDiff >= maxDays) { ... }

SK Chand Basha
Tera Sage

Hi @Pranita Bahugun  Please find this below notes

Correlation Rule Example.png

 

Rule-Based (Correlation Rule) Alert Groups.png

 

Scheduled Jobs.png