javascriptservicenow

GlideRecord ServiceNow Retrieving Int from Field for every record


I am new to Service Now and have tried many times to get the data I am looking for. I have a script that grabs all Virtual Machines in our database and takes the CPU count and the core count. I am looking to calculate the kWh usage for all our VMs. The formula is correct and I can run it just fine offline, but when it comes to Gliderecords, I think I am not grabbing the right data. any help would be greatly appreciated. Thank you

var calckWh = function() {
var gr = new GlideRecord('cmdb_ci_server');
var final_result = 0;
var numOfCores;
var numOfCPUs;

gr.addQuery('Model', 'Microsoft Corporation Virtual Machine');
gr.addQuery('CPU core count', '>=', 1);
var qc = gr.addQuery('Install Status', 'Installed');
qc.addOrCondition('Install Status', 'In Use');
gr.query();
while (gr.next()) {
    numOfCores = gr.getValue('cpu_core_count');
    numOfCPUs = gr.getValue('cpu_count');
    
    for (var j = 0; j < numOfCPUs; j++) {
        var TDP = 165;
        var load0 = 30;
        var load1 = 50;
        var load2 = 80;
        var load3 = 90;
        var load4 = 50;
        var load5 = 30;
        var hours = 4;

        var result = 0;
        var i;
        for (i = 0; i <= 5; i++) {
            var currentLoad = "load" + i;
            result += (numOfCores * TDP * (eval(currentLoad) / 100) * hours) / 1000;
        }
        final_result += result;
    }
}
return final_result;

This script grabs all installed/in-use VMs, and while there is another one in the records, it will run through, grab the current CPU and core count of the VM, then it will do the calculation of the number of times there are CPUs in the VM. it adds all of these calculations up to get the total kWh used for all of our active VMs. The only problem is I should be getting a number between 15,000-16,000, but this results in 229,000. I am not sure why.


Solution

  • You cannot use field labels or display values in an addQuery. You must use field names (which are always lower case) and field values. Your first addQuery should look something like this ...

    gr.addQuery('model_id', '15e8f8d537a01000deeabfc8bcbe5d46');
    

    ... although it is just an example. I do not know the sys_id of "Microsoft Corporation Virtual Machine" in your instance.

    If you do not want to hard-code the sys_id of the model, you can dot-walk to the model table like this...

    gr.addQuery('model_id.display_name', 'Microsoft Corporation Virtual Machine');
    

    "Installed" and "In Use" are two different names for the same thing, so you probably do not need an "OR" condition. Just use...

    gr.addQuery('install_status', '1');
    

    If you need to select multiple values, it is easier to use an "IN" operator

    gr.addQuery('install_status', 'IN', '1,4');
    

    I suspect that all your addQuery statements are being ignored, and that you are doing some sort of calculation on all the servers in your instance.

    The getValue method always returns a string, regardless of the underlying data type. Instead of ...

    numOfCores = gr.getValue('cpu_core_count');
    numOfCPUs = gr.getValue('cpu_count');
    

    it is better to write ...

    numOfCores = parseInt(gr.getValue('cpu_core_count'));
    numOfCPUs = parseInt(gr.getValue('cpu_count'));
    

    Another problem may be eval(currentLoad). You are not supposed to use eval in a ServiceNow script. You are supposed to use GlideEvaluator or GlideScopedEvaluator. In this case you do not even need to call eval. Just use an array. It is simpler and more efficient.

    var load = [30, 50, 80, 90, 50, 30];
    

    then

    result += (numOfCores * TDP * (load[i]) / 100) * hours) / 1000;