Linux统计cpu利用率
- 简介: 本文主要是介绍Linux环境下cpu利用率统计原理,并使用python脚本来统计一个时间段内的cpu利用率。
- 环境:本文的脚本都是运行于Centos7环境下,其他Centos版本或者ubuntu版本可能不适用
一、/proc文件系统的介绍
/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。
- /proc/cpuinfo文件(cpu相关信息)
- /proc/stat文件(所有cpu活动信息)
- /proc/pid/stat文件(进程相关信息)
- pid(进程ID)
- utime(该任务用户态运行时间)
- stime(核心态运行时间)
- cutime(所有已死线程用户态运行时间)
- cstime(所有已死线程和心态运行时间)
- 进程cpu总时间 = utime + stime + cutime + cstime
(单位是jiffies)
- /proc/pid/task/tid/stat文件 (线程相关信息)
- tid
- 线程cpu总时间 = utime + stime
- ps命令
- ps命令算出来的cpu使用率相对于进程启动时的平均值,随着进程运行时间的增大,该值会趋向于平缓。
- top命令
- 单核情况下Cpu使用率的计算
- 总的Cpu使用率计算
- 某一进程Cpu使用率的计算
- 多核情况下cpu使用率的计算
二、各资源利用率的计算
-
Linux计算cpu利用率
cat /proc/stat |grep cpu
- 大概有9-10列信息,不同系统显示的列数不一样。
- 第一行是其他行数据的总和
- 每列从左到右分别表示(如下图所示)(单位为jiffies):
- user:从系统启动开始累计到当前时刻,用户态的cpu时间(不包含nice值为负的进程所占用的cpu时间)
- nice:从系统启动开始累计到当前时刻,ncie为负的进程所占用的cpu时间
- system: 从系统启动开始累计到当前时刻,内核态所占用的cpu时间
- idle: 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间(cpu空闲时间)
- iowait:从系统启动开始累计到当前时刻,等待IO的时间
- irq: 从系统启动开始累计到当前时刻,系统中的硬中断时间
- softirq: 从系统启动开始累计到当前时刻,系统中的软中断时间
图中显示了该机器有20核,cpu 行的数据 (代表20个cpu总使用量)是cpu0-19各行数据的总和
注意:jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间
- t1-t2时间内的总CPU时间: total = t2时刻第一行每列之和-t1时刻的第一行每列之和
def get_system_cpu_usage(): """获取时刻t系统的CPU使用情况""" with open('/proc/stat') as f: lines = f.readlines() usage = 0 # for line in lines: # if 'cpu' in line: # line = line.split("\n")[0].split(' ') # usage += sum([float(l) for l in line[1:] if l]) # print(line) usage += sum([int(i) for i in lines[0].split('\n')[0].split(' ')[1:] if i]) print(usage) logging.debug("System_CPU_Usage:{}".format(usage)) return usage
时刻t cpu使用量为cpu行中各列数值之和,即usage=246270275+486352+ 。。。
- t1-t2时刻每核CPU时间 = t2时刻第一列除第一行以外的各行 - t1时刻第一列除第一行以外的各行
def get_system_usage_per_cpu(): """获取系统的每个CPU使用情况""" with open('/proc/stat') as f: lines = f.readlines() usage_per_cpu = 0 cpu_list = [line for line in lines[1:] if 'cpu' in line] per_cpu_list = [] idle_list = [] for cpu in cpu_list: row = cpu.split('\n')[0].split(' ') idle_list.append(int(row[4])) usage_per_cpu += sum([int(i)for i in row[1:] if i]) per_cpu_list.append(usage_per_cpu) usage_per_cpu = 0 # print(idle_list) # print(per_cpu_list) return idle_list, per_cpu_list
- t1-t2时间内的CPU空闲时间:idle = idle(t2)-idle(t1)
def get_system_idle_of_cpu(): """获取系统的cpu空闲时间总量""" with open('/proc/stat') as f: line = f.readline() return line.split(' ')[5]
line.split(" ")
出来的列表中间多了一个空格,所以取的是[5],正常的是idle在第4列 - t1-t2时间内cpu利用率:per_cpu = (total-idle)/total*100
def get_cpu_usage_and_idle(): """获取cpu总量和idle,返回(cpu_usage,idle)""" with open("/proc/stat") as f: line = f.readline() line = line.split(' ') return line[2], line[5] t1 = get_cpu_usage_and_idle() t2 = get_cpu_usage_and_idle() total = t2[0]-t1[0] idle = t2[1] - t1[1] cpu_percentage = (total-idle)/total*100
-
计算内存的利用率
- 文件
/proc/meminfo
存放内存的相关信息 cat /proc/meminfo
查看内存相关信息- 内存使用总量计算:
- used = total - free - buffers -cached
内存的数据比较清晰,这里不做太多的解释了
- used = total - free - buffers -cached
- 文件
-
计算网络使用信息
/proc/net/dev
- 读取网卡的发送和收取信息的总字节数,一般为eth0,多网卡多IP的情况下需要读取多块网卡的收发信息总字节数
-
获取网卡的IP地址和主机的cpu个数。