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

Get URL Parameter - server side script (portal or classic UI)

Classic UI : var sURL_editparam = gs . action . getGlideURI (). getMap (). get ( ' sysparm_aparameter ' ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); } Portal : var sURL_editparam = $sp . getParameter ( " sysparm_aparameter " ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); }

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 )){