nGrinder二次開發之監控機器性能數據

轉載:https://blog.csdn.net/neven7/article/details/53909256

1.背景

作性能測試時,統計性能數據分爲被壓系統的數據和被壓系統所在機器的數據,被壓系統所在機器的數據主要包括CPU利用率、內存使用率、網絡IO、磁盤IO和負載load;nGrinder默認只收集CPU, Memory, Received Byte/s, Sent Byte Per Secode/s,同時支持自定義數據收集,以前介紹過相關內容:nGrinder對監控機器收集自定義數據及源碼分析html

展現自定義數據需定時的寫文件,比較麻煩;本文將介紹如何改動源碼,直接展現CPU利用率、內存使用率、網絡IO、磁盤IO和負載load這5類數據。前端

2.實現

nGrinder是經過sigar api統計機器性能數據,sigar項目主頁:https://support.hyperic.com/display/SIGAR/Home, sigar api :http://cpansearch.perl.org/src/DOUGM/hyperic-sigar-1.6.3-src/docs/javadoc/org/hyperic/sigar/package-summary.htmljava

2-1.新增數據類型

ngrinder-core中package:org.ngrinder.monitor.share.domain下SystemInfo類定義了收集的數據類型,新增load、read、write和memUsedPercentage數據字段:linux

/** * modify by hugang */ public class SystemInfo extends MonitorInfo implements Serializable { private static final long serialVersionUID = -2995334644975166549L; /** * Header field of monitor status fields. */ // 新增load、磁盤IO和內存使用率 public static final String HEADER = "ip,system,collectTime,freeMemory," + "totalMemory,cpuUsedPercentage,receivedPerSec,sentPerSec,load,read,write,memUsedPercentage"; public boolean isParsed() { return true; } /** * Enum for the system type, linux or windows. */ public enum System { LINUX, WINDOW } private System system; // 網絡IO protected BandWidth bandWidth; private long totalCpuValue; private long idleCpuValue; private long freeMemory; private long totalMemory; private float cpuUsedPercentage; // load private double load; // 磁盤讀 private long read; // 磁盤寫 private long write; // 內存使用率 private double memUsedPercentage; ... set()、get()方法 public void parse(CompositeData cd) { // 新增 this.load = getDouble(cd, "load"); this.write = getLong(cd, "write"); this.read = getLong(cd, "read"); this.memUsedPercentage = getDouble(cd, "memUsedPercentage"); } public String toRecordString() { StringBuilder sb = new StringBuilder(); sb.append(ip).append(",").append(system).append(","); sb.append(DateUtils.getCollectTimeInLong(new Date(getCollectTime()))).append(",").append(freeMemory).append(","); sb.append(totalMemory).append(",").append(cpuUsedPercentage); if (bandWidth != null) { sb.append(",").append(bandWidth.getReceivedPerSec()).append(",").append(bandWidth.getSentPerSec()); } // 新類型load、read、write、memUsedPercentage數據拼接 sb.append(",").append(load).append(",").append(read).append(",").append(write).append(",").append(memUsedPercentage); if (customValues != null) { sb.append(",").append(customValues); } return sb.toString(); } public static class NullSystemInfo extends SystemInfo { private static final NullSystemInfo instance = new NullSystemInfo(); public static SystemInfo getNullSystemInfo() { return instance; } /** * Return the empty record string. * * @return null filled record string. * @see #toRecordString() */ @Override public String toRecordString() { StringBuilder sb = new StringBuilder(); sb.append("null").append(",").append("null").append(","); sb.append("null").append(",").append("null").append(","); sb.append("null").append(",").append("null"); if (bandWidth != null) { sb.append(",").append("null").append(",").append("null"); } // 拼接新類型數據爲"null" sb.append(",").append("null").append(",").append("null").append(",").append("null"); if (customValues != null) { int valueCount = StringUtils.countMatches(customValues, ",") + 1; for (int i = 0; i < valueCount; i++) { sb.append(",").append("null"); } } return sb.toString(); } public boolean isParsed() { return false; } } }

2-2.收集新增數據

ngrinder-core中package:org.ngrinder.monitor.collector下SystemDataCollector類中execute()方法實現了系統數據的收集:web

/** * modify by hugang */ public synchronized SystemInfo execute() { SystemInfo systemInfo = new SystemInfo(); systemInfo.setCollectTime(System.currentTimeMillis()); try { BandWidth networkUsage = getNetworkUsage(); BandWidth bandWidth = networkUsage.adjust(prev.getBandWidth()); systemInfo.setBandWidth(bandWidth); // getCombined()表明 Sum of User + Sys + Nice + Wait systemInfo.setCPUUsedPercentage((float) sigar.getCpuPerc().getCombined() * 100); Cpu cpu = sigar.getCpu(); systemInfo.setTotalCpuValue(cpu.getTotal()); systemInfo.setIdleCpuValue(cpu.getIdle()); Mem mem = sigar.getMem(); systemInfo.setTotalMemory(mem.getTotal() / 1024L); systemInfo.setFreeMemory(mem.getActualFree() / 1024L); // 新增load、磁盤IO和內存使用率 // The system load averages for the past 1, 5, and 15 minutes. double load = 0; long read = 0l; long write = 0l; load = sigar.getLoadAverage()[0]; //LOGGER.info("monitor system load:{}", load); // 全部的文件系統 FileSystem[] fileSystems = sigar.getFileSystemList(); // 獲取本地文件系統 List<String> localDevNames = new ArrayList<String>(); for(FileSystem fileSystem : fileSystems) { if(fileSystem.getType() == FileSystem.TYPE_LOCAL_DISK) { localDevNames.add(fileSystem.getDevName()); } } for(String localDevName : localDevNames) { read += sigar.getDiskUsage(localDevName).getReadBytes(); write += sigar.getDiskUsage(localDevName).getWriteBytes(); } //LOGGER.info("monitor system read:{}, write:{}", read, write); systemInfo.setLoad(load); systemInfo.setRead(read / 1024L); systemInfo.setWrite(write / 1024L); systemInfo.setMemUsedPercentage(mem.getUsedPercent()); systemInfo.setSystem(OperatingSystem.IS_WIN32 ? SystemInfo.System.WINDOW : SystemInfo.System.LINUX); systemInfo.setCustomValues(getCustomMonitorData()); } catch (Throwable e) { LOGGER.error("Error while getting system perf data:{}", e.getMessage()); LOGGER.debug("Error trace is ", e); } prev = systemInfo; return systemInfo; } 

2-3.前端monitor模板

ngrinder-controller下src/main/webapp/WEB-INF/ftl/perftest/detail_report/monitor.ftl定義了系統數據的可視化,修改以下:ajax

<#setting number_format="computer"> <#import "../../common/spring.ftl" as spring/> <div class="page-header page-header"> <h4>Monitor</h4> </div> <h6 id="cpu_usage_chart_header">CPU利用率(User + Sys + Nice + Wait),建議值:小於75%</h6> <div class="chart" id="cpu_usage_chart"></div> <h6 id="mem_usage_chart_header">Memory使用率,建議值:小於80%</h6> <div class="chart" id="mem_usage_chart"></div> <h6 id="received_byte_per_sec_chart_header">Received Byte Per Second</h6> <div class="chart" id="received_byte_per_sec_chart"></div> <h6 id="sent_byte_per_sec_chart_header">Sent Byte Per Second</h6> <div class="chart" id="sent_byte_per_sec_chart"></div> <h6 id="custom_monitor_chart_1_header">Load-average(one-minute)</h6> <div class="chart" id="custom_monitor_chart_1"></div> <h6 id="custom_monitor_chart_2_header">Physical Disk readBytes(total number of physical disk reads)</h6> <div class="chart" id="custom_monitor_chart_2"></div> <h6 id="custom_monitor_chart_3_header">Physical Disk writesBytes(total number of physical disk writes)</h6> <div class="chart" id="custom_monitor_chart_3"></div> <script> //@ sourceURL=/perftest/detail_report/monitor function getMonitorDataAndDraw(testId, targetIP) { var ajaxObj = new AjaxObj("/perftest/api/" + testId + "/monitor"); ajaxObj.params = { targetIP: targetIP, imgWidth: parseInt($("#cpu_usage_chart").width()) }; ajaxObj.success = function (data) { var interval = data.chartInterval; // modify by hugang // data.customData1爲load, data.customData2爲磁盤讀, data.customData3爲磁盤寫 drawChart('cpu_usage_chart', [data.cpu], formatPercentage, interval); // 調整爲內存使用率 drawChart('mem_usage_chart', [data.customData4], formatPercentage, interval); // load drawChart("custom_monitor_chart_1", [data.customData1], formatDouble, interval); drawChart("received_byte_per_sec_chart", [data.received], formatNetwork, interval); drawChart("sent_byte_per_sec_chart", [data.sent], formatNetwork, interval); // 磁盤讀 drawChart("custom_monitor_chart_2", [data.customData2], formatMemory, interval); // 磁盤寫 drawChart("custom_monitor_chart_3", [data.customData3], formatMemory, interval); createChartExportButton("<@spring.message "perfTest.report.exportImg.button"/>", "<@spring.message "perfTest.report.exportImg.title"/>"); }; ajaxObj.call(); } function drawChart(id, data, yFormat, interval) { return new Chart(id, data, interval, {yAxisFormatter: yFormat}).plot(); } function drawOptionalChart(id, data, interval, labels) { var result = drawChart(id, data, interval, labels); if (result.isEmpty()) { $("#" + id).hide(); $("#" + id + "_header").hide(); } } getMonitorDataAndDraw(${id}, "${targetIP}"); </script>

3.結果展現

對工程進行打包:spring

hugangdeMacBook-Pro:CPC hugang$ mvn clean -Dmaven.test.skip=true package

部署新war包,服務正常啓動後;需從新下載監控包,由於依賴的ngrinder-core.jar包有改動,從新啓動監控服務後,執行性能測試任務。windows

系統監控數據文件:/root/.ngrinder/perftest/0_999/${任務id}/report下 monitor_system_${ip}.data新增load、read、write和memUsedPercentage。api

前端展現:網絡

相關文章
相關標籤/搜索