- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 09:53 AM
I've added the Simultaneous Alert functionality written by ServiceNow Guru (Handling Simultaneous Updates in ServiceNow - ServiceNow Guru ) to my dev instance. With only minor changes, it works exactly as expected.
The request that has me stumped pertains to tracking how often this alert functionality is called.
I can't add a counter field to the record as that would trigger another update and likely cause a loop.
So adding a log statement that we can at least report on (in some fashion) sounds like the way to go. However, I can't find anything on writing to the system log from a client script. The "jslog" command writes to the JavaScript log, but that's only available while you're debugging. I need something I can check on a weekly basis to see how many records were simultaneously edited.
I'm pondering adding a new table simply for the purposes of tracking this data. My gut feeling though is that this will only be monitored for a short while and that a new table is probably tackling the issue with a sledgehammer.
Any suggestions are very much appreciated.
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 01:41 PM
If you use the code provided by Mark (crossfuze / servicenowguru) there is no need for additional ajax calls.
The onsubmit function already has an AjaxCall to verify the timestamps:
var ga = new GlideAjax('SimultaneousUpdateAlert');
ga.addParam('sysparm_name', 'checkUpdate');
ga.addParam('sysparm_tableName', tableName);
ga.addParam('sysparm_sysID', sysID);
ga.addParam('sysparm_user', g_user.userName);
ga.addParam('sysparm_silent_request', 'true'); // don't log on the server
ga.getXMLWait();
as is seems you only need to change sysparm_silent_request to false to make a log entry.
If not, check the Script Includes to find the one mentioned here and add your logging in there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 10:24 AM
Logging into the database from the client directly doesn't seem to be supported, but what you could easily do from your client script is call a really simple Scripted Web Service that reads something like:
(function () {
gs.log(request.message);
})();
If you named it LogService, you could call it from your client script like this:
function log_to_backend(msg) {
var ga = new GlideAjax("LogService");
ga.addParam('message', msg);
ga.getXML(function(resp) {
// don't need to do anything
// with the response
});
}
Hope this helps, good luck!
See Scripted Web Services - ServiceNow Wiki for more info on creating a Scripted Web Service.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 11:56 AM
Thanks for the advice - this sounds like a great solution (and potentially re-usable / expandable.)
I'm new to web services AND GlideAjax (of course) and I'm having some trouble getting this to work.
I added the code to my client script:
// For support of warning when two people are editing the same record
function onSubmit() {
//Only run if simultaneous update is enabled
if(g_scratchpad.simAlertEnabled == 'enabled' || g_scratchpad.simAlertEnabled == 'submit'){
var updatedOn = $('onLoad_sys_updated_on').value;
if(!updatedOn){
return;
}
//Get the button action, table name and sys_id of the record
var origAction = g_form.getFormElement().sys_action.value;
var tableName = g_form.getTableName();
var sysID = g_form.getUniqueValue();
//Query for update stamp for this record
jslog('UpdateAlert - Starting Simultaneous Update Alert Checking.');
var ga = new GlideAjax('SimultaneousUpdateAlert');
ga.addParam('sysparm_name', 'checkUpdate');
ga.addParam('sysparm_tableName', tableName);
ga.addParam('sysparm_sysID', sysID);
ga.addParam('sysparm_user', g_user.userName);
ga.addParam('sysparm_silent_request', 'true'); // don't log on the server
ga.getXMLWait();
var dbUpdatedOn = ga.getAnswer();
if(dbUpdatedOn){
var lastAlertNode = $('lastAlert');
var lastAlert = '';
if(lastAlertNode){
lastAlert = lastAlert.value;
}
if(!lastAlert || lastAlert == ''){
lastAlert = updatedOn;
}
//Set date string as date to do a greater than compare
var lastAlertDt = getDateFromFormat(lastAlert, 'yyyy-MM-dd HH:mm:ss');
var dbUpdatedOnDt = getDateFromFormat(dbUpdatedOn, 'yyyy-MM-dd HH:mm:ss');
jslog('UpdateAlert - Current record updated: ' + lastAlert + ', Database update time: ' + dbUpdatedOn);
jslog('UpdateAlert - Comparing values lastAlertDt: ' + lastAlertDt + ', dbUpdatedOnDt: ' + dbUpdatedOnDt);
//If the last alert time is less than the record update time then alert
if(lastAlertDt < dbUpdatedOnDt){
if($('lastAlert')){
//Stop the updateCheck listener
clearInterval(updateCheck);
lastAlertNode.value = dbUpdatedOn;
jslog('UpdateAlert - Updating lastAlert time to ' + dbUpdatedOn + ' and opening dialog.');
}
//NEW
var gr = new GlideRecord('sys_user');
gr.get(g_user.userID);
var userLanguage = gr.preferred_language;
if (userLanguage == 'fq'){
var uiPage = 'simultaneous_update_alert - fq';
} else {
var uiPage = 'simultaneous_update_alert - en';
}
log_to_backend("test test test");
//END NEW
//Open the 'Simultaneous Update Alert' dialog
var dialog = new GlideDialogWindow(uiPage, false);
dialog.setTitle('Simultaneous Update Alert');
dialog.setPreference('updatedOn', updatedOn);
dialog.setPreference('origAction', origAction);
dialog.setPreference('tableName', tableName);
dialog.setPreference('sysID', sysID);
dialog.setPreference('isSubmit', true); //Controls the appearance of OK/Cancel/Close buttons
dialog.removeCloseDecoration(); //Remove the dialog close icon
dialog.render();
return false;
}
}
}
}
function log_to_backend(msg) {
alert("into log_to_backend");
var ga = new GlideAjax("LogService");
ga.addParam('message', msg);
ga.getXML(function(resp) {
// don't need to do anything
// with the response
});
}
and created the web service with no Input or Output parameters:
I'm getting error messages in the logs:
These errors seem to be related to the naming of the web service and names not matching. I've double and triple checked and copy/pasted the names. I've tried it with and without Input and Output parameters in the web service. The only thing I've been able to confirm is that I am indeed falling into the log_to_backend function (having added an alert.)
Your continued assistance is very much appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 12:01 PM
Hi Sue:
The error message you got that gs.log is not allowed in Client Script is correct. It is only applicable for Server side scripts, like business rules, script include etc. Try using js.log.for client side debugging.
Hope this is helpful.
P.S. Hit it Correct and Helpful.
thanks
Danny
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 12:45 PM
Apologies, I had you create the wrong record for your web service.
What you actually need to create is a Script Include called LogService (instead of the Scripted Web Service I had you make before). Make sure the "Client Callable" box is checked.
Then change your logging service code to look like this:
var LogService = Class.create();
LogService.prototype = Object.extendsObject(AbstractAjaxProcessor, {
log: function () {
var message = this.getParameter('sysparm_message');
gs.log(message);
}
}
Also update your client code. You need the sysparm_ prefix, as well as telling your service which function you'd like called:
function log_to_backend(msg) {
var ga = new GlideAjax("LogService");
// send the name of the function on your
// ajax processor that you want to call
ga.addParam('sysparm_name', 'log');
// add parameter (the sysparm prefix
// is required)
ga.addParam('sysparm_message', msg);
ga.getXML(function(resp) {
// don't need to do anything
// with the response, we are
// just sending a message to
// be logged
});
}
Hopefully this all makes sense, and I didn't confuse you with the Scripted Web Service mumbo jumbo. I forgot that Script Includes can also make services you can call from the client. I had the calling procedure for Scripted Web Services wrong. Anyway, good luck again, hopefully you get some log rows from the client!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2016 01:41 PM
If you use the code provided by Mark (crossfuze / servicenowguru) there is no need for additional ajax calls.
The onsubmit function already has an AjaxCall to verify the timestamps:
var ga = new GlideAjax('SimultaneousUpdateAlert');
ga.addParam('sysparm_name', 'checkUpdate');
ga.addParam('sysparm_tableName', tableName);
ga.addParam('sysparm_sysID', sysID);
ga.addParam('sysparm_user', g_user.userName);
ga.addParam('sysparm_silent_request', 'true'); // don't log on the server
ga.getXMLWait();
as is seems you only need to change sysparm_silent_request to false to make a log entry.
If not, check the Script Includes to find the one mentioned here and add your logging in there.