转载: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对监控机器收集自定义数据及源码分析

展示自定义数据需定时的写文件,比较麻烦;本文将介绍如何改动源码,直接展示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.html

2-1.新增数据类型

ngrinder-core中package:org.ngrinder.monitor.share.domain下SystemInfo类定义了收集的数据类型,新增load、read、write和memUsedPercentage数据字段:

/**
* 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()方法实现了系统数据的收集:

/**
* 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定义了系统数据的可视化,修改如下:

<#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.结果展示

对工程进行打包:

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

部署新war包,服务正常启动后;需重新下载监控包,因为依赖的ngrinder-core.jar包有改动,重新启动监控服务后,执行性能测试任务。

系统监控数据文件:/root/.ngrinder/perftest/0_999/${任务id}/report下 monitor_system_${ip}.data新增load、read、write和memUsedPercentage。

前端展示:

nGrinder二次开发之监控机器性能数据的更多相关文章

  1. 使用Jyhon脚本和PMI模块监控WAS性能数据

    使用Jyhon脚本和PMI模块监控WAS性能数据的优点有: 1.可以使用非交互的方式远程获取数据 2.不需要图形化模块支持 3.对各种was版本的兼容性较高 4.使用方便,官方自带 缺点也有很多: 1 ...

  2. Python监控进程性能数据并画图保存为PDF文档

    引言 利用psutil模块(https://pypi.python.org/pypi/psutil/),可以很方便的监控系统的CPU.内存.磁盘IO.网络带宽等性能參数,下面是否代码为监控某个特定程序 ...

  3. ENVI二次开发模式下的Landsat数据读取

    从usgs网站或者马里兰大学下载TM或Landsat原始数据,数据可能包括9个tif数据,两个txt文件和一个gtf文件.示例结构如下: ENVI下可以直接打开*_MTL.txt文件打开,打开后波段列 ...

  4. ODI KM二次开发手册

    ODI KM二次开发手册   分类: ODI(16) 目录(?)[+] 1 引言 1.1 编写目的 本手册面向的读者对象为具备数据集成业务知识及对ODI操作了解的开发人员,作为其完成基于ODI基础上K ...

  5. [开源地址] 放弃Flink,.NET5.0开发CSharpFlink,简要设计、部署及二次开发说明。

    github地址:https://github.com/wxzz/CSharpFlinkgitee地址:https://gitee.com/wxzz/CSharpFlink 1 概述及背景 我们有一个 ...

  6. 性能测试工具 nGrinder 项目剖析及二次开发

    转:https://testerhome.com/topics/4225 0.背景 组内需要一款轻量级的性能测试工具,之前考虑过LR(太笨重,单实例,当然它的地位是不容置疑的),阿里云的PTS(htt ...

  7. nGrinder对监控机器收集自定义数据及源码分析

    转载:https://blog.csdn.net/neven7/article/details/50782451 0.背景 性能测试工具nGrinder支持在无需修改源码的情况下,对目标服务器收集自定 ...

  8. nagios二次开发(四)---nagios监控原理和nagios架构简介

    nagios监控原理 下面根据上面摘自网络的原理图对nagios的监控原理进行一下简单的说明: 1.nagios通过nsca进行被动监控.那么什么是被动监控呢?被动监测:就是指由被监测的服务器主动上传 ...

  9. zabbix nagios 类nagios 之 不以性能为前提的开发和监控都是瞎扯淡

    从最初的nagios到现在强大的zabbix 3.0,我想说,不以性能为前提的开发和监控都是瞎扯淡? 首先我对这两款监控软件的认识: zabbix,很多企业都在用,给人的感觉是很炫,不过我个人觉得虽然 ...

随机推荐

  1. Java多线程编程——volatile关键字

    (本篇主要内容摘自<Java多线程编程核心技术>) volatile关键字的主要作用是保证线程之间变量的可见性. package com.func; public class RunThr ...

  2. 【Python初级】由判定回文数想到的,关于深浅复制,以及字符串反转的问题

    尝试用Python实现可以说是一个很经典的问题,判断回文数. 让我们再来看看回文数是怎么定义的: 回数是指从左向右读和从右向左读都是一样的数,例如1,121,909,666等 解决这个问题的思路,可以 ...

  3. 阿里云下Linux服务器安装JDK、Tomcat

    阿里云服务器相信大家越来越熟悉,刚开始接触,将基本的java软件安装做点记录: 1.配置阿里云的yum仓库: 获取仓库配置 wget http://mirrors.aliyun.com/repo/Ce ...

  4. FastReport.Net使用:[30]对话框使用

    使用对话框需要知道的地方  1.按钮的DialogResult属性. 假如DialogResult属性值为OK的按钮被点击,报表将会展现后面的对话框或者报表页:如果属性值为None,则停留在当前窗体: ...

  5. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

  6. Linux下Apache2.2和PHP5的安装配置

    Linux下Apache2.2和PHP5的安装配置 环境介绍 我安装使用的Linux版本为CentOS6.5最精简版,Apache为2.2.29,PHP版本为5.4.28. 系统安装 首先安装Cent ...

  7. 单端通用ISM频段接收器 Si4313

    Si4313芯片是单端通用ISM频段接收器,工作频率为240-960MHz,可编程接收频率带宽为2.6-260kHz,接收灵敏度为-118dBm,数据速率为0.2-128kb/s,采用FSK.GFSK ...

  8. @ResponseBody,@RequestBody,@PathVariable

    最近需要做些接口服务,服务协议定为JSON,为了整合在Spring中,一开始确实费了很大的劲,经朋友提醒才发现,SpringMVC已经强悍到如此地步,佩服! 相关参考: Spring 注解学习手札(一 ...

  9. 修改Linux默认启动级别或模式

    在Linux中有7种启动级别,默认是X-Window,像是Windows的窗口模式,而Linux的操作和配置一般我们都采用输入命令的方式来完成,像DOS操作系统一样,如何让Linux一启动就进入这种模 ...

  10. linux下的系统调用函数到内核函数的追踪

    http://blog.csdn.net/maochengtao/article/details/23598433