Skip to content
event-management logo

Event Management for ServiceNow

event-management

Build ServiceNow Event Management — push events to em_event, write event rules with severity transforms, configure alert correlation, dependent-CI rollups, and metric-threshold event generation.

groeimetai/snow-flow0installs78stars

SKILL.md

Full skill instructions

Event Management for ServiceNow

Event Management consolidates events from monitoring tools, correlates them, and creates actionable alerts.

Event Flow

Monitoring Tools (Nagios, SCOM, etc.)
    ↓
Events (em_event)
    ↓ Event Rules
Alerts (em_alert)
    ↓ Alert Management Rules
Incidents/​Changes

Key Tables

TablePurpose
em_eventRaw events from sources
em_alertProcessed alerts
em_event_ruleEvent processing rules
em_alert_correlation_ruleAlert correlation
em_connectorEvent source connectors

Events (ES5)

Create Event Programmatically

// Create event (ES5 ONLY!)
var event = new GlideRecord("em_event")
event.initialize()

// Required fields
event.setValue("source", "Custom Monitor")
event.setValue("node", "server01.example.com")
event.setValue("type", "CPU High")
event.setValue("severity", 3) // 1=Critical, 2=Major, 3=Minor, 4=Warning, 5=OK

// Event key for deduplication
event.setValue("event_class", "performance")
event.setValue("message_key", "cpu_high_server01")

// Description
event.setValue("description", "CPU usage exceeded 90% threshold")
event.setValue(
  "additional_info",
  JSON.stringify({
    cpu_percent: 95,
    process: "java",
    duration: "5 minutes",
  }),
)

// CI binding
event.setValue("cmdb_ci", getCISysId("server01"))

// Resource and metric
event.setValue("resource", "CPU")
event.setValue("metric_name", "cpu_usage")

event.insert()

Event via REST API

// Push event via REST (External script - ES5 ONLY!)
var request = {
  records: [
    {
      source: "External Monitor",
      node: "app-server-01",
      type: "Application Error",
      severity: "2",
      message_key: "app_error_" + Date.now(),
      description: "Application threw critical exception",
      additional_info: '{"error_code": "E500", "module": "payment"}',
    },
  ],
}

// POST to: /​api/​global/​em/​jsonv2

Event Rules (ES5)

Event Processing Rule

// Create event rule (ES5 ONLY!)
var rule = new GlideRecord("em_event_rule")
rule.initialize()

// Rule identification
rule.setValue("name", "High CPU Alert")
rule.setValue("description", "Create alert for high CPU events")
rule.setValue("order", 100)
rule.setValue("active", true)

// Event filter (which events to process)
rule.setValue("filter", "type=CPU High^severity<=3")

// Actions
rule.setValue("create_alert", true)
rule.setValue("alert_severity", 3)

// Transform settings
rule.setValue("transform_type", true)
rule.setValue("new_type", "Performance - CPU")

// CI binding
rule.setValue("ci_binding_type", "node")

rule.insert()

Event Rule Script (ES5)

// Event rule advanced script (ES5 ONLY!)
// Table: em_event_rule, field: script

;(function runRule(event, rule) {
  // Get additional info
  var addInfo = {}
  try {
    addInfo = JSON.parse(event.additional_info)
  } catch (e) {
    addInfo = {}
  }

  // Set severity based on CPU percentage
  var cpuPercent = parseFloat(addInfo.cpu_percent) || 0

  if (cpuPercent >= 95) {
    event.severity = 1 // Critical
  } else if (cpuPercent >= 90) {
    event.severity = 2 // Major
  } else if (cpuPercent >= 80) {
    event.severity = 3 // Minor
  }

  // Enrich description
  event.description = event.description + " (Current: " + cpuPercent + "%)"

  // Set time to clear (auto-close if OK event not received)
  event.u_time_to_clear = 900 // 15 minutes

  return true // Continue processing
})(event, rule)

Alerts (ES5)

Alert Lifecycle

Open
    ↓ Acknowledge
Acknowledged
    ↓ Investigate
In Progress
    ↓ Resolution
Resolved
    ↓ Close
Closed

Flapping ← Multiple severity changes

Alert Management Rule

// Create alert management rule (ES5 ONLY!)
var amRule = new GlideRecord("em_alert_management_rule")
amRule.initialize()

amRule.setValue("name", "Auto-create Incident for Critical Alerts")
amRule.setValue("description", "Create P1 incident for critical alerts on production CIs")
amRule.setValue("order", 100)
amRule.setValue("active", true)

// Alert filter
amRule.setValue("filter", "severity=1^cmdb_ci.u_environment=production")

// Action: Create incident
amRule.setValue("create_incident", true)
amRule.setValue("incident_priority", 1)
amRule.setValue("incident_assignment_group", getGroupSysId("NOC"))

amRule.insert()

Manual Alert Processing (ES5)

// Process alert manually (ES5 ONLY!)
function acknowledgeAlert(alertSysId, notes) {
  var alert = new GlideRecord("em_alert")
  if (!alert.get(alertSysId)) {
    return { success: false, message: "Alert not found" }
  }

  // Validate state
  if (alert.getValue("state") !== "Open") {
    return { success: false, message: "Alert is not in Open state" }
  }

  // Acknowledge
  alert.setValue("state", "Acknowledged")
  alert.setValue("acknowledged_by", gs.getUserID())
  alert.setValue("acknowledged_at", new GlideDateTime())

  // Add notes
  if (notes) {
    alert.work_notes = "Acknowledged: " + notes
  }

  alert.update()

  return { success: true, number: alert.getValue("number") }
}

Alert Correlation (ES5)

Correlation Rule

// Create correlation rule (ES5 ONLY!)
var corrRule = new GlideRecord("em_alert_correlation_rule")
corrRule.initialize()

corrRule.setValue("name", "Server Down Correlation")
corrRule.setValue("description", "Correlate all alerts when a server goes down")
corrRule.setValue("active", true)

// Parent alert filter
corrRule.setValue("parent_filter", "type=Server Down^severity=1")

// Child alert filter
corrRule.setValue("child_filter", "cmdb_ci.u_hosted_on=javascript:parent.cmdb_ci")

// Correlation window
corrRule.setValue("time_window", 300) // 5 minutes

// Action
corrRule.setValue("set_child_severity", true)
corrRule.setValue("new_child_severity", 4) // Warning

corrRule.insert()

Custom Correlation Script (ES5)

// Alert correlation script (ES5 ONLY!)
// Correlate database alerts with application alerts

var AlertCorrelation = Class.create()
AlertCorrelation.prototype = {
  initialize: function () {},

  /​**
   * Find related alerts for correlation
   */
  findRelatedAlerts: function (parentAlertSysId) {
    var parent = new GlideRecord("em_alert")
    if (!parent.get(parentAlertSysId)) {
      return []
    }

    var relatedAlerts = []
    var parentCI = parent.getValue("cmdb_ci")
    var parentTime = new GlideDateTime(parent.getValue("sys_created_on"))

    // Time window: 5 minutes before/​after parent
    var windowStart = new GlideDateTime(parentTime)
    windowStart.addSeconds(-300)
    var windowEnd = new GlideDateTime(parentTime)
    windowEnd.addSeconds(300)

    // Find alerts on dependent CIs
    var dependents = this._getDependentCIs(parentCI)

    var alert = new GlideRecord("em_alert")
    alert.addQuery("cmdb_ci", "IN", dependents.join(","))
    alert.addQuery("sys_created_on", ">=", windowStart)
    alert.addQuery("sys_created_on", "<=", windowEnd)
    alert.addQuery("sys_id", "!=", parentAlertSysId)
    alert.addQuery("parent_alert", "") // Not already correlated
    alert.query()

    while (alert.next()) {
      relatedAlerts.push({
        sys_id: alert.getUniqueValue(),
        number: alert.getValue("number"),
        cmdb_ci: alert.cmdb_ci.getDisplayValue(),
        severity: alert.getValue("severity"),
      })
    }

    return relatedAlerts
  },

  _getDependentCIs: function (parentCISysId) {
    var dependents = []

    var rel = new GlideRecord("cmdb_rel_ci")
    rel.addQuery("parent", parentCISysId)
    rel.addQuery("type.name", "Depends on::Used by")
    rel.query()

    while (rel.next()) {
      dependents.push(rel.getValue("child"))
    }

    return dependents
  },

  /​**
   * Correlate alerts under parent
   */
  correlate: function (parentAlertSysId, childAlertSysIds) {
    for (var i = 0; i < childAlertSysIds.length; i++) {
      var child = new GlideRecord("em_alert")
      if (child.get(childAlertSysIds[i])) {
        child.setValue("parent_alert", parentAlertSysId)
        child.work_notes = "Correlated with parent alert"
        child.update()
      }
    }
  },

  type: "AlertCorrelation",
}

Metrics (ES5)

Create Metric Event

// Create metric event for threshold monitoring (ES5 ONLY!)
function createMetricEvent(ciSysId, metricName, value, thresholds) {
  var severity = 5 // OK by default

  // Determine severity based on thresholds
  if (value >= thresholds.critical) {
    severity = 1
  } else if (value >= thresholds.major) {
    severity = 2
  } else if (value >= thresholds.minor) {
    severity = 3
  } else if (value >= thresholds.warning) {
    severity = 4
  }

  // Only create event if not OK
  if (severity < 5) {
    var event = new GlideRecord("em_event")
    event.initialize()
    event.setValue("source", "Metric Monitor")
    event.setValue("cmdb_ci", ciSysId)
    event.setValue("type", metricName + " Threshold")
    event.setValue("severity", severity)
    event.setValue("metric_name", metricName)
    event.setValue("message_key", metricName + "_" + ciSysId)
    event.setValue("description", metricName + " is at " + value + " (Threshold: " + getThresholdName(severity) + ")")
    event.insert()
  }

  return severity
}

function getThresholdName(severity) {
  var names = { 1: "Critical", 2: "Major", 3: "Minor", 4: "Warning", 5: "OK" }
  return names[severity]
}

MCP Tool Integration

Available Tools

ToolPurpose
snow_query_tableQuery events, alerts, and event rules
snow_artifact_manageFind related artifacts (action='find')
snow_execute_scriptTest event scripts
snow_create_eventTrigger system events

Example Workflow

// 1. Query open alerts
await snow_query_table({
  table: "em_alert",
  query: "state=Open^severity<=2",
  fields: "number,description,cmdb_ci,severity,source",
})

// 2. Find unprocessed events
await snow_query_table({
  table: "em_event",
  query: "state=Ready",
  fields: "source,node,type,severity,description",
})

// 3. Create test event
await snow_execute_script({
  script: `
        var event = new GlideRecord('em_event');
        event.initialize();
        event.source = 'Test';
        event.type = 'Test Event';
        event.severity = 4;
        event.node = 'test-server';
        gs.info('Created: ' + event.insert());
    `,
})

Best Practices

  1. Event Deduplication - Use message_key properly
  2. CI Binding - Bind events to CIs for impact
  3. Severity Mapping - Consistent severity levels
  4. Correlation - Reduce alert noise
  5. Time Windows - Configure appropriate windows
  6. Auto-closure - Set time-to-clear for transient issues
  7. Monitoring - Track event processing health
  8. ES5 Only - No modern JavaScript syntax

More skills from groeimetai

reporting-dashboards logo
groeimetai/snow-flow

reporting-dashboards

Build ServiceNow reports (list/bar/pie/line/pivot/single-score) on sys_report, sys_dashboard layouts with widget placement, scheduled report delivery, and drill-down configuration.

78 0
View
rest-integration logo
groeimetai/snow-flow

rest-integration

Make outbound REST calls from ServiceNow with sn_ws.RESTMessageV2 — basic/bearer/OAuth/API-key auth, error handling by status code, response parsing, sys_rest_message records, and retry with exponential backoff.

78 0
View
mcp-tool-discovery logo
groeimetai/snow-flow

mcp-tool-discovery

Use tool_search to discover and enable lazy-loaded Serac MCP tools (snow_*, jira_*, github_*, etc). Explains naming conventions, search strategies, and always-available activity tools.

78 0
View
atf-testing logo
groeimetai/snow-flow

atf-testing

Build ServiceNow Automated Test Framework tests and suites — impersonation, form steps, assertions, server-side script steps, test parameters, and execution via snow_create_atf_test / snow_execute_atf_test.

78 0
View
import-export logo
groeimetai/snow-flow

import-export

Move data in and out of ServiceNow — CSV parsing into import sets, GlideImportSetTransformer runs, CSV/JSON/XML exports, scheduled data sources, bulk update and deleteMultiple safety patterns.

78 0
View
discovery-patterns logo
groeimetai/snow-flow

discovery-patterns

Configure ServiceNow Discovery — schedules, IP ranges, credential affinities, MID Server assignment, custom probes/sensors, identification rules, and run-status monitoring on discovery_* tables.

78 0
View
csm-patterns logo
groeimetai/snow-flow

csm-patterns

Build ServiceNow Customer Service Management — customer_account, customer_contact, sn_customerservice_case routing, service entitlements with usage decrement, and Customer Portal case submission widgets.

78 0
View
data-policies logo
groeimetai/snow-flow

data-policies

Manage ServiceNow dictionary (sys_dictionary), table/field creation, choice lists, dictionary overrides, and sys_data_policy2 rules that enforce mandatory/read-only/visible field behavior on the data layer.

78 0
View
mobile-development logo
groeimetai/snow-flow

mobile-development

Configure ServiceNow Mobile (Now Mobile/Agent) — sys_sg_mobile_app screens, card builders, push notifications, offline sync rules, mobile actions for barcode/GPS, and offline-queue change processing.

78 0
View
email-notifications logo
groeimetai/snow-flow

email-notifications

Create ServiceNow sysevent_email_action notifications — templates with substitution variables, mail scripts for dynamic content/recipients/attachments, custom events, weights, and digest configuration.

78 0
View
es5-compliance logo
groeimetai/snow-flow

es5-compliance

Enforce ES5-only syntax for ServiceNow server-side scripts (Rhino engine) — convert const/let, arrow functions, template literals, destructuring, for-of, and async/await to ES5 equivalents.

78 0
View
change-management logo
groeimetai/snow-flow

change-management

Create and transition ServiceNow change requests (normal/standard/emergency), change tasks, affected CIs, approval routing, CAB scheduling, and conflict detection across maintenance windows.

78 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View