Writing a log statement from a client script.

Sue Frost
Giga Guru

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.

1 ACCEPTED SOLUTION

Daniel Draes
ServiceNow Employee
ServiceNow Employee

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.


View solution in original post

11 REPLIES 11

andyh_
Giga Contributor

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.


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:


webservice.png



I'm getting error messages in the logs:


errors.png



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.


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


andyh_
Giga Contributor

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!


Daniel Draes
ServiceNow Employee
ServiceNow Employee

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.