Skip to main content

ServiceNow- useful admin focused widget and portal page for Dynatrace ITOM - serves as a test harness

 

(does not include the script include code)

 HTML:

<div>
       <H1>DYNATRACE DOCUMENTATION</H1>
       </div>
<div class="ghost">
        <p><a href="https://www.dynatrace.com/support/help/setup-and-configuration/integrations/third-party-integrations/problem-notification-systems/servicenow-integration/
">Click to view Dynatrace Online Documentation</a></p>
</div>

<div>
        <H1>DYNATRACE ENVIRONMENTS</H1>
</div>
<div class="ghost">
        <p>
          STAGING:<br/>
          yyyyy.live.dynatrace.com
        </p>
        <p>
              PROD:<br/>
          ppppp.live.dynatrace.com
        </p>
</div>

<div>
       <H1>Script include calls</H1>
</div>
<div class="ghost">
      <H2>Extract Alert info</H2>
      <div>
             <label class="col-sm-2 control-label">Enter Alert number here</label>
             <input class="form-control" value ='Alert0022348' id='alert_num'>     
      </div><br/>
      <div class="form-group">
             <button ng-click="runtheoperation_alert()" class="btn btn-info">Click to extract tags from the JSON</button>
      </div>
      <div>
             <h3>Alert tags:</h3>
             <p>
              key tags extracted from em_alert.additional_info field, not the full list necessarily
             </p>
             <textarea readonly id="results_add_info" rows="10" style="width:100%">{{c.dynatraceADDLINFO}}</textarea>
     </div>
</div>  

<div class="ghost">
 <div>
           <H2>Callback Function Test</H2>
           <label for="dt_env">Select Dynatrace environment</label>

           <select name="dynatrace_environment" id="dynatrace_environment">
              <option value="staging">STAGING (yyyyyy)</option>
              <option value="production">PROD (pppppp)</option>
           </select>
 </div>
 <div>
          <label class="col-sm-2 control-label">Enter entity name here</label>
          <input class="form-control" value ='PROCESS_GROUP_INSTANCE-629BAB231Fxxxxx' id='dynatrace_entity_name'>     
 </div>
 
  <br/>

  <div class="form-group">
          <button ng-click="runtheoperation()" class="btn btn-info">Click to check problem details/root cause SVCOFF</button>
  </div>
  <div>
      <h3>Problem Details (Rootcause) SVCOFF:</h3>
      <textarea readonly id="results_svcoff" rows="1" style="width:50%">{{c.dynatraceSVCOFF}}</textarea>
  </div>
  <div>
      <h3>SVCOFF (Service Offering) name:</h3>
      <textarea readonly id="svcoff_name" rows="1" style="width:50%">{{c.SVCOFF_name}}</textarea>
  </div>
  <div>
      <h3>Full problem details (rootcauseinfo) payload:</h3>
      <div class="well">
          <textarea readonly id='results_full' rows="10" style="width:100%;">{{c.dynatraceResponse}}</textarea>
      </div>
  </div>
    
  <div>
       <h2>Get Random Allocation SVCOFF (from full problem details payload):</h2>
  </div>
  <div class="form-group">
       <button ng-click="runtheoperation_random()" class="btn btn-info">Click to randomly allocate svcoff</button>
  </div>
  <div>
    <h3>Random allocated SVCOFF:</h3>
    <textarea readonly id="result_random" rows="1" style="width:50%">{{c.dynatraceRandomSVCOFF}}</textarea>
  </div>
</div>
<br/>   
 
<div>
      <H1>EXAMPLE EVENT PAYLOADS</H1>
      <H2>Open Alert</H2>
</div>
<div class="ghost">
      {{::data.example_payload_open}}
</div>
<div>
  <H2>Closed Alert</H2>
</div>
<div class="ghost">
  {{::data.example_payload_closed}}
</div> 

client script

api.controller=function($scope) {
  /* widget controller */
  var c = this;
    c.dynatraceResponse='';
      c.dynatraceADDLINFO='';
      c.dynatraceRandomSVCOFF='';
      c.SVCOFF_name='';
   
    $scope.runtheoperation = function() {
        
            //console.log("message", 'run the op');
        c.server.get({
               action: "get_rootcause",
             msg : "Running REST API GET operation to retrieve rootcause SVCOFF from Dynatrace...",
               sn_env : angular.element($('#dynatrace_environment')).val(),
               entity : angular.element($('#dynatrace_entity_name')).val()
           }).then(function(r){
               var responseData=r.data.rootcauseinfo;
                         var responseSVCOFF=r.data.rootcausesvcoff;
                         var SVCOFF_name=r.data.svcoff_name;
                    //alert('responseData='+responseData);
              //c.dynatraceResponse=responseData.join('\n');  
                        c.dynatraceResponse=responseData;
                        c.dynatraceSVCOFF=responseSVCOFF;
                        c.SVCOFF_name=SVCOFF_name;
        });
  };
    
    $scope.runtheoperation_alert = function() {
        
            //console.log("message", 'run the op');
        c.server.get({
               action: "get_additionalinfo",
             msg : "extracting additional_info from alert...",
               alert_num : angular.element($('#alert_num')).val()
           }).then(function(r){
               var responseAddInfoData=r.data.alertinfo;
                        
                    //alert('responseData='+responseData);
              //c.dynatraceResponse=responseData.join('\n');  
                        c.dynatraceADDLINFO=responseAddInfoData;
        });
  };
    
    $scope.runtheoperation_random = function() {
        alert(angular.element($('#dynatrace_environment')).val() + '; alert='+angular.element($('#alert_num')).val()+ ' (in "Enter Alert number here" box)');
            //console.log("message", 'run the op');
        c.server.get({
               action: "get_randomsvcoff",
               msg : "allocating random SVCOFF from problem details response payload...",
                         sn_env : angular.element($('#dynatrace_environment')).val(),
                         alert_num : angular.element($('#alert_num')).val()
           }).then(function(r){
                   
                        //alert('Extracting from: ' + angular.element($('#results_full')).val());
               var responseRandomSVCOFF=r.data.randomsvcoff;
                        
                    c.dynatraceRandomSVCOFF=responseRandomSVCOFF;
        });
  };
}


server script

(function() {
    /* populate the 'data' object */
    /* e.g., data.table = $sp.getValue('table'); */
    var si=new sgo_itomevents_libraries();
    data.example_payload_open = si.ExamplePayloadEvents_open();
    
    data.example_payload_closed = si.ExamplePayloadEvents_resolved();
    
    //data.rootcausesvcoff='<click button>';
    
    if (input ){
        if (input.action === "get_rootcause"){
             var si=new  sgo_itomevents_libraries();
             data.rootcausesvcoff=(rootcause_info(input.sn_env, input.entity, si));
            var sNum=data.rootcausesvcoff+"";
             data.svcoff_name=getSVCOFFname(sNum);
             
           data.rootcauseinfo=(rootcause_fullpayload(si));
     }
        if (input.action === "get_additionalinfo"){
           data.alertinfo=(rootcause_addl_info(input.alert_num));
     }
        if (input.action === "get_randomsvcoff"){
           data.randomsvcoff=(random_svcoff(input.alert_num, input.sn_env));
     }
  }


function random_svcoff(alert_number, env){
    var resp='';
    var sEnv='yyyyy';
    if (env=='production'){
        sEnv='ppppp';
    }
    var grAlert=new GlideRecord('em_alert');
    if (grAlert.get('number', alert_number)){
     var si=new  sgo_itomevents_libraries();
     resp=si.getRandomSVCOFFfromTags(grAlert,sEnv);
    }
    return resp;
}

function rootcause_fullpayload(si){
    
    //gs.addInfoMessage('entityname='+entityname);
    //gs.addInfoMessage('environment='+environment);
    
    
    var resp=si.getRootCauseInfo_rawPayload();
    
    //gs.addInfoMessage('resp='+resp);
    
    return resp;
}
    function rootcause_info(environment,entityname, si){
    
    //gs.addInfoMessage('entityname='+entityname);
    //gs.addInfoMessage('environment='+environment);
    
    var resp2=si.getRootCauseInfo(entityname,environment);
    //gs.addInfoMessage('resp='+resp2);
    return resp2;
}

function rootcause_addl_info(alert_number){
    
    var si=new  sgo_itomevents_libraries();
    var resp=si.extractAlertAdditionalInfoTags(alert_number);
    
    //gs.addInfoMessage('resp='+resp);
    
    return resp;
}
    function getSVCOFFname(svcoffNum){
       
        var sReturn='';
        var grSO=new GlideRecord('service_offering');
        grSO.addQuery('number', svcoffNum);
        grSO.query();
        if (grSO.next()){
            sReturn=grSO.getValue("name");
        }
        return sReturn;
    }
    })();

CSS

div.ghost{
  background: ghostwhite;
  font-size: 15px;
  padding: 10px;
  border: 1px solid lightgray;
  margin: 10px;
}

Comments

Popular posts from this blog

ServiceNow timeout settings for virtual agent chat

  After connecting to live agent User is connected to live agent and not responding to live agent chat or distracted. The below properties controls the timeout settings, the OOB settings for reminder is [180 sec] and for cancelling the chat is [360 sec]. The job is default configured to 2 min so I believe no tweaking is required here.  Property -   com.glide.cs.idle_chat_reminder_timeout                  com.glide.cs.idle_chat_cancel_timeout Scheduled job   - Idle Chat Timer Task   https://community.servicenow.com/community?id=community_article&sys_id=1453b03bdbaad0109e691ea668961929   (ServiceNow ) 

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){...