添砖加瓦:Linux系统监测

前言 

  前段时间因为项目需求,需要实时获取系统当前的运行状态,遂查阅了不少资料,基于/proc目录下的部分文件,实现了系统CPU、内存、网络和磁盘的实时监测。

一、CPU使用情况获取

  获取CPU使用情况是从/proc/stat文件中获取的,/proc/stat 包含了系统启动以来的许多关于kernel和系统的统计信息,其中包括CPU运行情况、中断统计、启动时间、上下文切换次数、运行中的进程等等信息

  

cpu  1149770 0 309685 239871041 7 0 0 0
cpu0 1149770 0 309685 239871041 7 0 0 0
intr 0
swap 0 0

ctxt 892809418
btime 1525518899
processes 379246
procs_running 1
procs_blocked 0

“cpu” 这行展示所有CPU在user-sapce、kernel mode上的一些时间,接着是各个CPU的统计情况。
“intr” 这行 展示系统中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
的中断自系统启动以来所发生的次数。
“ctxt” 这行展示自系统启动以来CPU发生的上下文交换的次数。
“btime”这行展示从系统启动到现在为止的时间(以Epoch时间开始计算, 1970-01-01 00:00:00 +0000 (UTC)),单位为秒。
 
“processes” 这行展示自系统启动以来所创建的任务的个数目(total_forks)。
“procs_running” 这行显示当前运行队列的任务的数目。
“procs_blocked” 这行显示当前被阻塞的任务的数目。

  计算CPU占用率的话,只需要关注第一行即可,各参数含义如下:

  


user


从系统启动开始累计到当前时刻,用户态的CPU时间,不包含nice值为负进程。


nice


从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间


system


从系统启动开始累计到当前时刻,核心时间


idle


从系统启动开始累计到当前时刻,除IO等待时间以外其它等待时间


iowait


从系统启动开始累计到当前时刻,IO等待时间


irq


从系统启动开始累计到当前时刻,硬中断时间


softirq


从系统启动开始累计到当前时刻,软中断时间

  因为/proc/stat中的数值都是从系统启动开始累计到当前时刻的积累值,所以需要在不同时间点t1和t2取值进行比较运算,当两个时间点的间隔较短时(我取的是1s),就可以把这个计算结果看作是CPU的即时利用率。

  CPU的即时利用率的计算公式:

  CPU在t1到t2时间段总的使用时间 = ( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1)

  CPU在t1到t2时间段空闲使用时间 = (idle2 - idle1)

  CPU在t1到t2时间段即时利用率 =  1 - CPU空闲使用时间 / CPU总的使用时间

  源码

void get_cpuinfo(CPU_PACKED &cpuinfo)
{
	char buff[256] = {0};
	ifstream in("/proc/stat");
	if (!in)
	{
		cout << "get cpu info failed" << endl;
		return;
	}

	in.getline(buff, sizeof(buff));
	stringstream ss(buff);
	ss >> cpuinfo.name;
	ss >> cpuinfo.user;
	ss >> cpuinfo.nice;
	ss >> cpuinfo.system;
	ss >> cpuinfo.idle;
	ss >> cpuinfo.iowait;
	ss >> cpuinfo.irq;
	ss >> cpuinfo.softirg;

	in.close();
}
double calc_cpuoccupy(CPU_PACKED cpuinfo1, CPU_PACKED cpuinfo2)
{
	double info1d = cpuinfo1.user + cpuinfo1.nice + cpuinfo1.system + cpuinfo1.idle + cpuinfo1.softirg + cpuinfo1.iowait + cpuinfo1.irq;
	double info2d = cpuinfo2.user + cpuinfo2.nice + cpuinfo2.system + cpuinfo2.idle + cpuinfo2.softirg + cpuinfo2.iowait + cpuinfo2.irq;

	double sub1 = cpuinfo1.idle;
	double sub2 = cpuinfo2.idle;
	double cpu_use;

	if ((sub1 - sub2) != 0)
		cpu_use = 100.0 - ((sub2 - sub1) / (info2d - info1d)) * 100.0;
	else
		cpu_use = 0;

	//double cpu_use = cpuinfo1.user/info1d;
	return cpu_use;
}

二、内存使用情况

  内存使用情况是从/proc/meminfo文件中获取的

[root ~]# cat /proc/meminfo
MemTotal:        1048576 kB
MemFree:          927940 kB
Cached:            31468 kB
Buffers:               0 kB
Active:            46764 kB
Inactive:          50516 kB
Active(anon):      32312 kB
Inactive(anon):    33500 kB
Active(file):      14452 kB
Inactive(file):    17016 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:        131072 kB
SwapFree:          86620 kB
Dirty:                16 kB
Writeback:             0 kB
AnonPages:         65812 kB
Shmem:               164 kB
Slab:              23172 kB
SReclaimable:       6552 kB
SUnreclaim:        16620 kB

  这里关注的是MemTotal、MemFree和Cached三个值,使用中的内存 = MemTotal-MemFree-Cached

void calc_memoccupy(MEM_PACKED &meminfo)
{
	char buff[256] = {0};
	string name;
	unsigned long free_mem;
	unsigned long cached;
	int index = 0;
	ifstream in("/proc/meminfo");
	if (!in)
	{
		cout << "get cpu info failed" << endl;
		return;
	}

	stringstream ss;
	while (!in.eof() && index < 4)
	{
		in.getline(buff, sizeof(buff));
		ss.str("");
		ss << buff;
		if (index == 0)
		{
			ss >> name;
			ss >> meminfo.total_mem;
		}
		else if (index == 1)
		{
			ss >> name;
			ss >> free_mem;
		}
		else if (index == 3)
		{
			ss >> name;
			ss >> cached;
		}
		index++;
	}

	meminfo.used_mem = meminfo.total_mem - free_mem - cached;

	in.close();
}

 三、网络传输(上传和下载的速度)

  网络使用情况是从/proc/net/dev文件中获取的

[root ~]# cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo: 4057260174  245081    0    0    0     0          0         0 4057260174  245081    0    0    0     0       0          0
venet0: 21610450920 22790055    0    0    0     0          0         0 22011662266 22005133    0  148    0     0       0          0

  网络上传和下载速度是根据网卡venet0单位时间(1s)内发收的字节数计算出来的

void read_netdev(unsigned long &ups, unsigned long &downs)
{
	ifstream in("/proc/net/dev");
	if (!in)
	{
		cout << "get network info failed" << endl;
		return;
	}
	string line;
	std::vector<string> lines;
	while (!in.eof())
	{
		getline(in, line);
		if (in.fail())
			break;
		lines.push_back(line);
	}
	vector<string> items = splitstring(lines[lines.size() - 1]);
	ups = atol(items[1].c_str());
	downs = atol(items[9].c_str());

	in.close();
}

void calc_netspeed(NET_PACKED &netinfo)
{
	unsigned long ups1, ups2, downs1, downs2;
	read_netdev(ups1, downs1);
	sleep(1);
	read_netdev(ups2, downs2);

	netinfo.upspeed = (float)(ups2 - ups1);
	netinfo.downspeed = (float)(downs2 - downs1);
}

 四、硬盘使用情况

  硬盘使用情况分两部分:硬盘空间使用情况和硬盘实时的读写情况。

  硬盘的使用情况可以通过statfs()函数获取,读写速度是通过单位时间(1s)内读写的扇区个数来计算的

   [root ~]# cat /proc/diskstats
   1    0 ram0 0 0 0 0 0 0 0 0 0 0 0
   1    1 ram1 0 0 0 0 0 0 0 0 0 0 0
   1    2 ram2 0 0 0 0 0 0 0 0 0 0 0
   1    3 ram3 0 0 0 0 0 0 0 0 0 0 0
   1    4 ram4 0 0 0 0 0 0 0 0 0 0 0
   1    5 ram5 0 0 0 0 0 0 0 0 0 0 0
   1    6 ram6 0 0 0 0 0 0 0 0 0 0 0
   1    7 ram7 0 0 0 0 0 0 0 0 0 0 0
   1    8 ram8 0 0 0 0 0 0 0 0 0 0 0
   1    9 ram9 0 0 0 0 0 0 0 0 0 0 0
   1   10 ram10 0 0 0 0 0 0 0 0 0 0 0
   1   11 ram11 0 0 0 0 0 0 0 0 0 0 0
   1   12 ram12 0 0 0 0 0 0 0 0 0 0 0
   1   13 ram13 0 0 0 0 0 0 0 0 0 0 0
   1   14 ram14 0 0 0 0 0 0 0 0 0 0 0
   1   15 ram15 0 0 0 0 0 0 0 0 0 0 0
   7    0 loop0 0 0 0 0 0 0 0 0 0 0 0
   7    1 loop1 0 0 0 0 0 0 0 0 0 0 0
   7    2 loop2 0 0 0 0 0 0 0 0 0 0 0
   7    3 loop3 0 0 0 0 0 0 0 0 0 0 0
   7    4 loop4 0 0 0 0 0 0 0 0 0 0 0
   7    5 loop5 0 0 0 0 0 0 0 0 0 0 0
   7    6 loop6 0 0 0 0 0 0 0 0 0 0 0
   7    7 loop7 0 0 0 0 0 0 0 0 0 0 0
   8    0 sda 30526 2009 1087215 193416 115412736 102258023 1811485376 87116184 0 18093240 87295592
   8    1 sda1 22754 483028 5686677 45493256
   8    2 sda2 166 662 8265 66120
   8    3 sda3 6528 570989 123499806 987893792
   8    4 sda4 2887 30896 88516083 708124240
   9    0 md0 0 0 0 0 0 0 0 0 0 0 0

  

void calc_rwspeed(unsigned long &readsectors, unsigned long &writesectors)
{
	ifstream in("/proc/diskstats");
	if (!in)
	{
		cout << "get disk speed info failed with Reason:" << strerror(errno) << endl;
		return;
	}
	string line;
	while (!in.eof())
	{
		getline(in, line);
		size_t pos = line.find("sda");
		if (pos < line.size())
		{
			line = line.substr(pos + 4, line.size());
			break;
		}
	}

	vector<string> items = splitstring(line);
	readsectors = atol(items[2].c_str());
	writesectors = atol(items[6].c_str());

	in.close();
}

void calc_diskoccupy(string path, DISK_PACKED &diskinfo)
{
	struct statfs disk;
	if (statfs(path.c_str(), &disk) == -1)
	{
		cout << "Failed to get disk info with Reason:" << strerror(errno) << endl;
		return;
	}

	diskinfo.total_disk = disk.f_blocks * disk.f_bsize;
	diskinfo.avail_disk = disk.f_bavail * disk.f_bsize;
	diskinfo.free_disk = disk.f_bfree * disk.f_bsize;

	unsigned long reads1, writes1, reads2, writes2;
	calc_rwspeed(reads1, writes1);
	sleep(1);
	calc_rwspeed(reads2, writes2);

	diskinfo.read_speed = (reads2 - reads1) * disk.f_bsize;
	diskinfo.write_speed = (writes2 - writes1) * disk.f_bsize;
}

  完整代码详见我的Gihub

原文地址:https://www.cnblogs.com/lianshuiwuyi/p/9126834.html

时间: 2024-11-08 21:48:07

添砖加瓦:Linux系统监测的相关文章

Linux系统监测—查询系统CPU,内存,IO信息

查看系统负载的工具:uptime,w,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数, 可运行:运行态,占用CPU,或就绪态,等待CPU调度. 不可打扰:阻塞,正在等待I/O 例1. 使用uptime查看系统负载 # uptime 19:26:17 up 49 days, 7:34, 1 user, load average: 0.67, 0.51, 0.41 这里我们关注的是最后三列,即系统1分钟.5分钟.15分钟内的平均负载,判断一个系统负载是否偏高需要计算单核CPU的

Linux 系统监测工具

uptime [~]$ uptime13:24:46 up 207 days, 3:27, 2 users, load average: 1.45, 1.34, 1.33 system time: 系统当前时间13:24:46 system uptime:系统运行时间207天3小时27分 users:当前登入系统的用户数 load average:过去的1分钟,5分钟,15分钟系统的负载情况,越小越好. 将单核CPU理解为一座桥,而系统中的任务看成一辆辆要过桥的汽车.当负载为1时,桥满负荷,汽车

linux系统带宽监测脚本

服务器可能经常遇到服务器出带宽跑满,不知如何查询被哪个进程占用的情况,有一款开源的英文软件iftop功能比较强大可以查询相关信息,可能刚接触linux系统的朋友不太会使用,在此写了一个功能比较简单无需安装的带宽查看脚本,可以查询linux服务器当前带宽使用量,有需要的朋友可以试试  快速使用方法  1.下载脚本 ssh登录服务器后输入:  英文版: wget http://jinxiang.oss-cn-hangzhou.aliyuncs.com/vmnetcheck.sh  中文版: gbk版

监测linux系统负载与CPU、内存、硬盘、用户数的shell脚本

本节主要内容: 利用Shell脚本来监控Linux系统的负载.CPU.内存.硬盘.用户登录数. 一.linux系统告警邮件脚本 # vim /scripts/sys-warning.sh #!/bin/bash #site: www.jquerycn.cn #监控系统负载与CPU.内存.硬盘.登录用户数,超出警戒值则发邮件告警. #提取本服务器的IP地址信息 IP=`ifconfig eth0 | grep "inet addr" | cut -f 2 -d ":"

linux性能监测与优化

top命令 命令功能 top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息 的监测系统性能和运行信息的实用工具. 命令语法 top(选项) 选项说明 -b:以批处理模式操作; -d:屏幕刷新间隔时间. uptime 命令功能 uptime命令能够打印系统总共运行了多长时间和系统的平均负载. 命令语法 uptime(选项) 选项说明 -v:显示指令的版本信息. free命令 命令功能 free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内 核使用的内存缓冲区. 命令

系统监测和性能分析工具

作为一名linux运维工程师来说,对linux系统的日常管理,检测和系统性能的分析是必不可少的.也有一些针对系统监测和性能分析的工具.咱们现在就来了解一下. tcpdump命令: 网络抓包工具,过滤数据包或者定制输出格式: 常用选项: -n :  用IP地址表示主机,用数字表示端口号. -i  : 监听网卡接口, -i  any :   抓取所有网卡接口的数据包. -v  :  输出详细信息. -t :  不打印时间戳 -e :  显示以太网帧头部信息. -x  :  以十六进制数显示数据包的内

Linux系统平均负载3个数字的含义

越来越多人开始接触Linux操作系统,从VPS到无线路由的刷机系统(如OpenWRT.Tomato),同时也必不可少地会在各式各样的探针和系统监测界面上看到"系统平均负载"或者"Load Average"这样的字眼,但是它并不像我们习惯中Windows.Mac操作系统提供百分比显示CPU.内存占用率,而是以几个用空格隔开的浮点数来表示系统平均负载,那么它们到底是什么意思呢?又如何衡量系统负载及系统的稳定性呢? 系统平均负载-基本解释 在Linux shell下,有很

Linux系统下强大的lsof命令使用宝典

lsof命令简介: lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以,lsof的功能很强大.一般root用户才能执行lsof命令,普通用户可以看见/usr/sbin/lsof命令,但是普通用户执行会显示“permission denied”.因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的. usage: [-?abhlnNoOPRstUv

linux系统/var/log目录下的信息详解

一./var目录 /var 所有服务的登录的文件或错误信息文件(LOG FILES)都在/var/log下,此外,一些数据库如MySQL则在/var/lib下,还有,用户未读的邮件的默认存放地点为/var/spool/mail 二.:/var/log/ 系统的引导日志:/var/log/boot.log例如:Feb 26 10:40:48 sendmial : sendmail startup succeeded就是邮件服务启动成功! 系统日志一般都存在/var/log下常用的系统日志如下:核心