Integrating External Events with Event Management

From ServiceNow Wiki
Home > Deliver > IT Operations Management > Integrating External Events with Event Management
Jump to: navigation, search
Note
Note: This article applies to Fuji. For more current information, see Get Started with Event Management at http://docs.servicenow.com

The ServiceNow Wiki is no longer being updated. Please refer to http://docs.servicenow.com for the latest product documentation.


1 Overview

You can create a scripted integration with Event Management to push external events from monitoring tools such as Icinga and Nagios. If your monitoring tool is a supported event source, you can instead configure the instance to pull events using a MID Server (starting with the Fuji release). In either case, the system uses the REST API to add events to the Event [em_event] table.

There are two scripted-integration options to push events:

The evt_mgmt_integration role is required to perform these tasks.

2 Required Event Information

All incoming events must have a value in the Event class [em_event.event_class] field (starting with Fuji release). If your external event source does not populate this value, copy the value of the Source [em_event.source] field.

3 Sending Single Records

3.1 Connecting the Monitoring Tool to Event Management

To connect and log in to the ServiceNow instance:

  • Install Python on the system running the monitoring tool.
  • Configure the system running the monitoring tool to send the sendEventServiceNow.py command with the following information:
    • Instance REST API endpoint
    • Instance credentials

For example:

python sendEventServiceNow.py --endPoint="https://<name_of_instance>/api/now/table/em_event" --user="admin" 
    --password="pwd"

The parameters for connecting to the instance are described in the following table.

Field Description
endpoint The endpoint of the web service—that is, the target instance.
  • Type: String (REST API URL)
  • Default value: http://localhost:8080/api/now/table/em_event
user The user name credential.
  • Type: String (username)
  • Default value: admin
password The user password credential.
  • Type: String (password)
  • Default value: admin

3.2 Sending Events to Event Management

To send events to event management, execute the following Python command for each event, with an argument preceded by two hyphens for each parameter of the Event object:

python sendEventServiceNow.py

This command inserts an event record into the Event [em_event] table, with each parameter of the Event object inserted into the corresponding field. For example, the following command creates an event record in the table, and populates the Source, Node, Type, Resource, and Severity fields:

python sendEventServiceNow.py --source="Source1" --node="lnux100" --type="High Memory Utilization" 
    --resource="RAM" --severity="1"

To avoid sending authentication parameters each time, edit the Python script to update the default values of the endpoint, username, and password parameters. See Connecting the Monitoring Tool to Event Management for the values expected.

3.3 Event Object

Use the parameters of the Event object with the sendEventServiceNow.py to send event information to an instance. The parameters of the Event object match the fields of the Event [em_event] table.

Name Description
source The source, or monitoring tool, that generates the event, such as Icinga.
  • Type: String
  • Default value: none
  • Maximum length: 100
node The physical device or virtual entity that is being monitored.
  • Type: String
  • Default value: none
  • Maximum length: 100
type The type of event, such as storage or performance.
  • Type: String
  • Default value: none
  • Maximum length: 100
resource [Optional] The resource on the node that generates the event, such as disk or database server.
  • Type: String
  • Default value: none
  • Maximum length: 100
eventClass [Required] The category that identifies the event.
  • Type: String
  • Default value: none
  • Maximum length: 100
messageKey The event's unique key. If this field is empty, Event Management will concatenate the values of the source, type, node, and resource parameters.
  • Type: String
  • Default value: none
  • Maximum length: 100
severity [Optional] The severity of the event: 1 = Critical, 2 = Major, 3 = Minor, 4 = Warning, or 0 = Clear.
  • Type: choice
  • Default value: 3
  • Maximum length: 40
timeOfEvent [Optional] The time of the event occurrence in GMT format. If a value is not provided, the script defaults to the current system time.
  • Type: GlideDateTime
  • Default value: none
  • Maximum length: 40
description [Optional] A description of the event.
  • Type: String
  • Default value: none
  • Maximum length: 4000
additionalInfo [Optional] A JSON string that represents additional information for the event, typically an event metric and value. This information is required to use alert threshold rules (available starting with the Fuji release).
  • Type: String (JSON string)
  • Default value: none
  • Maximum length: 4000
ciIdentifier [Optional] A JSON string that represents a configuration item.
  • Type: String
  • Default value: none
  • Maximum length: 1000

3.4 Python Script

The sendEventServiceNow.py script sends the Event object data to the Event [em_event] table. The script is shown below. This script sends a single record. To send a stream of records, see Sending Streaming Events.

'''
This python script sends an Event to the ServiceNow instance Event Management system via REST. 
Sample usage: 
python sendEventServiceNow.py --source="Source1" --node="lnux100" --type="High Memory Utilization" --resource="RAM" --severity="1"
'''

import base64
import datetime
import json
from optparse import OptionParser
import urllib2

def defineOptions():
    parser = OptionParser();
    
    # How to connect/login to the ServiceNow instance
    parser.add_option("--endPoint", dest="endPoint", help="The endpoint of the web service", default="http://localhost:8080/api/now/table/em_event")
    parser.add_option("--user", dest="user", help="The user name credential", default="admin")
    parser.add_option("--password", dest="password", help="The user password credential", default="admin")

    # Fields on the Event
    parser.add_option("--source", dest="source", help="Source of the event", default="Icinga")
    parser.add_option("--eventClass", dest="eventClass", help="Event class", default="Icinga")
    parser.add_option("--messageKey", dest="messageKey", help="Message key", default="")       
    parser.add_option("--node", dest="node", help="Name of the node", default="Default-Node")    
    parser.add_option("--type", dest="type", help="Type of event", default="High Memory Utilization")        
    parser.add_option("--resource", dest="resource", help="Represents the resource event is associated with", default="Default-Disk")    
    parser.add_option("--severity", dest="severity", help="Severity of event", default="3")    
    parser.add_option("--timeOfEvent", dest="timeOfEvent", help="Time of event in GMT format", default="")
    parser.add_option("--description", dest="description", help="Event description", default="Default event description")    
    parser.add_option("--additionalInfo", dest="additionalInfo", help="Additional event information that can be used for third-party integration or other post-alert processing", default="{}")
    parser.add_option("--ciIdentifier", dest="ciIdentifier", help="Optional JSON string that represents a configuration item", default="{}")

    (options, args) = parser.parse_args()
    return options

def execute():
    if (options.timeOfEvent == ""):
      options.timeOfEvent = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S');
      
    if options.eventClass == "":
        options.eventClass = options.source
   
    if options.messageKey == "":
        options.messageKey = options.source +"__" + options.node +"__" + options.type + "__" + options.resource

    data = {"source" : options.source, "node" : options.node , "type" : options.type, 
            "resource" : options.resource, "severity" : options.severity, 
            "time_of_event" : options.timeOfEvent, "description" : options.description,
            "additional_info" : options.additionalInfo, "ci_identifier" : options.ciIdentifier,
            "event_class" : options.eventClass, "message_key": options.messageKey}
    data = json.dumps(data)

    headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
    request = urllib2.Request(url=options.endPoint, data=data, headers=headers)
    base64string = base64.urlsafe_b64encode('%s:%s' % (options.user, options.password))
    request.add_header("Authorization", "Basic %s" % base64string)  
    f = urllib2.urlopen(request)
    f.read()
    f.close()
  
if __name__ == '__main__':
  options = defineOptions();
  execute();

4 Streaming Events over a Persistent Connection

You can use this Java snippet to authenticate once and stream events over a persistent connection. The code below shows how to authenticate and set up a session and reuse that for each event. This gives you a faster throughput than authenticating each time.

private static final String URL = "https://<name_of_instance>/api/now/table/em_event";
private static final String USER_NAME = "admin";
private static final String PASSWORD = "pwd";

private CookieStore cookie;

public void authenticate() {
    // Establish an authenticated session and store the cookie for later use
    DefaultHttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet(URL);
    request.setHeader(new BasicScheme().authenticate(
        new UsernamePasswordCredentials(USER_NAME, PASSWORD), request,
        new BasicHttpContext()));
    client.execute(request);
    cookie = client.getCookieStore();
    client.getConnectionManager().shutdown();
}

public void sendEvent(String event) {	
    DefaultHttpClient client = new DefaultHttpClient();
    HttpPost postRequest = new HttpPost(URL);
	
    // Use the stored authentication cookie
    client.setCookieStore(cookie);
	
    StringEntity input = new StringEntity(event);
    input.setContentType("application/json");
    postRequest.setEntity(input);
	
    client.execute(postRequest);
    client.getConnectionManager().shutdown();
}
Was this article helpful?
Yes, I found what I needed
No, I need more assistance