
scotthall
ServiceNow Employee
Options
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 09-25-2020 12:11 PM
My colleague,
We used a Listener Transform Script to receive Google's JSON and map it to the Event record in ServiceNow.
This is definitely work-in-progress, needs further work to meet specific customer needs, and is not officially supported. It should give a head start on getting this set up though.
Some prerequisites:
- The service account in ServiceNow used by Google to connect to the instance should have "Web service access only" checked, and must have the "evt_mgmt_integration" role assigned.
- The url for Google's webhook to post to is https://{Instance-name}.service-now.com/api/global/em/inbound_event?source={URL_parameter_value}
- URL_parameter_value comes from the "URL parameter value" field on the Listener Transform Script record.
- Note: for customers hosted in GCC, the URL is slightly different: https://{Instance-name}.servicenowservices.com/api/global/em/inbound_event?source={URL_parameter_value}
We configured the Listener Transform Script as follows:
- Name: Google Monitoring Test Events Instance
- Type: Instance (you could use a MID server to receive events as well, but we didn't for testing)
- URL parameter value: googleJson (this can be anything you want, it forms the end of the URL referenced above)
- Header name: generic-header
- Header value: true
Script:
(function process( /*RESTAPIRequest*/ request, body) {
/*Function that receives a JSON object, adding all its fields to the Additional information object. The field name is a concatenation of the field key and the parent field key if it exists.*/
function updateAdditionalInfo(event, field, jsonObject, additionalInfo) {
for (var key in jsonObject) {
var newKey = key;
if (field != "") {
newKey = field + '_' + key;
}
/* SAMPLE PAYLOAD FROM GOOGLE
REFERENCED HERE https://cloud.google.com/monitoring/support/notification-options
{
"incident": {
"incident_id": "f2e08c333dc64cb09f75eaab355393bz",
"resource_id": "i-4a266a2d",
"resource_name": "webserver-85",
"state": "open",
"started_at": 1385085727,
"ended_at": null,
"policy_name": "Webserver Health",
"condition_name": "CPU usage",
"url": "https://console.cloud.google.com/monitoring/alerting/incidents?project=PROJECT_ID",
"summary": "CPU for webserver-85 is above the threshold of 1% with a value of 28.5%"
},
"version": 1.1
}
*/
// PERFORM YOUR SPECIFIC TRANSFORMS HERE
/* Unclear if this should be mapped to message_key
if(key == "incident_id") {
event.message_key = jsonObject[key];
}*/
/* Alternate to resource_name below, not sure which one to use
if(key == "resource_id") {
event.node = jsonObject[key];
}*/
if (key == "resource_name") { // OR resource_id depending on need
event.node = jsonObject[key];
}
// Map Google state of "open" to SN state of "New", otherwise assume it's "Closing"
if (key == "state") {
if (jsonObject[key] == "open") {
event.resolution_state = "New";
} else {
event.resolution_state = "Closing";
}
}
// Map epoch time to SN date time
if (key == "started_at") { // 1385085727
event.time_of_event = convertEpochToSNTime(jsonObject[key]);
}
/* Not sure this is used in SN
if (key == "ended_at") { // 1385085738
if (jsonObject[key] > 0) {
event.time_of_event = convertEpochToSNTime(jsonObject[key]);
}
}*/
// Map policy_name to metric_name
if (key == "policy_name") {
event.metric_name = jsonObject[key];
}
// Map condition_name to resource and type
if (key == "condition_name") {
event.resource = jsonObject[key];
event.type = jsonObject[key];
}
// Concatenate the url and summary to the event description text
if (key == "summary") {
// If description is empty, add a newline before, otherwise just add the summary or url
if (event.description == "") {
event.description = jsonObject[key];
} else {
event.description = jsonObject[key] + '\n' + event.description;
}
}
if (key == "url") {
// If description is empty, add a newline before, otherwise just add the summary or url
if (event.description == "") {
event.description = jsonObject[key];
} else {
event.description = event.description + '\n' + jsonObject[key];
}
}
additionalInfo[newKey] = jsonObject[key];
}
}
function convertEpochToSNTime(epochTime) {
var gdt = new GlideDateTime();
gdt.setNumericValue(epochTime * 1000);
return gdt.toString();
}
try {
gs.info("TransformEvents_generic received body:" + body);
var jsonObject = JSON.parse(body);
var event = new GlideRecord('em_event');
//TODO: Need to define
event.source = "Google";
//TODO: Need to define. Specific instance of the source. For example, SCOM 2012 on 10.20.30.40
event.event_class = "GoogleMonitoring";
//TODO: Set the event severity. All Google events will be 1-Critical. Scale is 1-5.
event.severity = "1";
var additionalInfo = {};
updateAdditionalInfo(event, "", jsonObject, additionalInfo);
/*Iterates over Additional information JSON object and adds all nested objects' fields as fields of the Additional information object*/
var notDone = true;
while (notDone) {
notDone = false;
for (var key in additionalInfo) {
if (Object.prototype.toString.call(additionalInfo[key]) == '[object Object]') {
notDone = true;
updateAdditionalInfo(event, key, additionalInfo[key], additionalInfo);
additionalInfo[key] = "";
}
}
}
gs.info("TransformEvents_generic generated additional information:" + JSON.stringify(additionalInfo));
event.additional_info = JSON.stringify(additionalInfo);
event.insert();
} catch (er) {
gs.error(er);
status = 500;
return er;
}
return "success";
})(request, body);
Labels:
- 898 Views