ServiceNow GlideRecord获取CPU数据计算VM kWh结果异常求助
问题分析与修复方案
核心问题
你编写的能耗计算脚本离线运行结果在15000-16000 kWh区间,但在ServiceNow中执行后结果高达229000,大概率是GlideRecord数据查询环节出现偏差,导致计算基数远超预期。
可能的问题点
- 查询条件用了显示名而非后台字段/系统值
Model字段直接匹配显示值可能失效:ServiceNow中cmdb_ci_server的model字段是关联cmdb_model表的引用字段,直接写显示名可能匹配到非目标设备,或者因大小写/空格差异漏筛/多筛。Install Status用显示值错误:Installed和In Use是前端显示文本,后台存储的是系统数值(1=已安装,2=在用),用显示值会导致条件失效,返回大量不符合状态的服务器。
- 数值字段未做类型转换
gr.getValue()返回的是字符串类型,直接用于循环或计算可能引发隐式转换错误,比如字符串"2"被当作非数值处理,或循环逻辑异常放大结果。 - eval函数存在风险
ServiceNow的脚本安全环境可能限制eval执行,导致负载值读取异常,间接影响计算结果。
修复步骤
第一步:修正GlideRecord查询逻辑
var gr = new GlideRecord('cmdb_ci_server'); // 用后台字段名+关联表名称匹配模型 gr.addQuery('model.name', 'Microsoft Corporation Virtual Machine'); gr.addQuery('cpu_core_count', '>=', 1); // 用系统数值匹配安装状态 var qc = gr.addQuery('install_status', 1); // 已安装 qc.addOrCondition('install_status', 2); // 在用 gr.query();
第二步:确保数值字段类型正确
将getValue返回的字符串转为数值,避免类型错误:
numOfCores = parseInt(gr.getValue('cpu_core_count'), 10) || 0; numOfCPUs = parseInt(gr.getValue('cpu_count'), 10) || 0; // 跳过CPU数据异常的设备 if (numOfCores === 0 || numOfCPUs === 0) { gs.warn('服务器' + gr.name + 'CPU数据异常,跳过计算'); continue; }
第三步:替换eval优化负载计算
用数组存储负载值,避免eval的安全风险:
var loads = [30, 50, 80, 90, 50, 30]; var result = 0; for (var i = 0; i < loads.length; i++) { result += (numOfCores * TDP * (loads[i] / 100) * hours) / 1000; }
第四步:添加日志调试
在循环中加入日志,确认查询到的设备是否符合预期:
while (gr.next()) { gs.info('当前计算设备: ' + gr.name + ' | 核心数: ' + numOfCores + ' | CPU数量: ' + numOfCPUs); // 后续计算逻辑... }
通过系统日志 > 应用日志查看输出,确认是否多算了非目标设备。
完整修复后的脚本
var calckWh = function() { var gr = new GlideRecord('cmdb_ci_server'); var final_result = 0; var numOfCores; var numOfCPUs; gr.addQuery('model.name', 'Microsoft Corporation Virtual Machine'); gr.addQuery('cpu_core_count', '>=', 1); var qc = gr.addQuery('install_status', 1); qc.addOrCondition('install_status', 2); gr.query(); while (gr.next()) { numOfCores = parseInt(gr.getValue('cpu_core_count'), 10) || 0; numOfCPUs = parseInt(gr.getValue('cpu_count'), 10) || 0; if (numOfCores === 0 || numOfCPUs === 0) { gs.warn('服务器' + gr.name + 'CPU数据异常,跳过计算'); continue; } var TDP = 165; var hours = 4; var loads = [30, 50, 80, 90, 50, 30]; for (var j = 0; j < numOfCPUs; j++) { var result = 0; for (var i = 0; i < loads.length; i++) { result += (numOfCores * TDP * (loads[i] / 100) * hours) / 1000; } final_result += result; } } gs.info('总能耗计算结果: ' + final_result); return final_result; }
内容的提问来源于stack exchange,提问作者user12763568
相关产品推荐
相关产品推荐

