Unix系推崇一个观点,Everything is a file 。对于一些系统以及进程信息,kernel会以文件系统的系统挂载在proc和sys目录,也就是常说的procfs,sysfs虚拟文件系统。包括CPU,内存和硬盘等信息。当然对于系统监控来说,这也是重要的数据源。
proc的目录看起来是下面这样的,那些数字都是进程的PID,其他的是一些系统系,比如cpuinfo记录者硬件的CPU信息:
接下来我们看一下进程PID里面的信息,记录者此进程的启动命令,参数等信息。
ls /proc/
1 1170 1345 19 2116 304 382 406 787 942 consoles interrupts kpageflags pagetypeinfo sysrq-trigger
10 12 14 1911 22 305 383 408 8 955 cpuinfo iomem loadavg partitions sysvipc
1022 1205 15 1922 24 31 384 41 824 96 crypto ioports locks sched_debug thread-self
105 1215 16 1928 25 32 387 42 85 967 devices irq mdstat schedstat timer_list
1059 1216 174 2 257 33 389 422 86 979 diskstats kallsyms meminfo scsi tty
11 122 175 20 26 34 398 462 87 994 dma kcore misc self uptime
1122 1243 176 2098 26150 35 4 555 88 acpi driver key-users modules slabinfo version
1134 1269 177 21 27 36 40 556 89 buddyinfo execdomains keys mounts softirqs version_signature
1147 1289 18 2100 28 37 400 6 9 bus fb kmsg mpt stat vmallocinfo
1152 13 183 2114 29 379 402 639 90 cgroups filesystems kpagecgroup mtrr swaps vmstat
1166 1340 186 2115 30 381 404 7 908 cmdline fs kpagecount net sys zoneinfo
ls /proc/1/
attr cmdline environ io mem ns pagemap sched smaps_rollup syscall wchan
autogroup comm exe limits mountinfo numa_maps patch_state schedstat stack task
auxv coredump_filter fd loginuid mounts oom_adj personality sessionid stat timers
cgroup cpuset fdinfo map_files mountstats oom_score projid_map setgroups statm timerslack_ns
clear_refs cwd gid_map maps net oom_score_adj root smaps status uid_map
sysfs主要记录的系统的设备信息,如果是一个docker0的虚拟网卡:
ls /sys/devices/virtual/net/docker0/
addr_assign_type bridge carrier_changes dev_port gro_flush_timeout link_mode operstate power statistics uevent
addr_len brif carrier_down_count dormant ifalias mtu phys_port_id proto_down subsystem
address broadcast carrier_up_count duplex ifindex name_assign_type phys_port_name queues tx_queue_len
brforward carrier dev_id flags iflink netdev_group phys_switch_id speed type
刚才上面已经提到procfs是监控系统重要的数据源之一,接下来用几个实例来说明如何监控这些资源。
CPU
我们经常说机器的CPU又到95%了,是不是又被挖矿了?那么这个95%又是怎么计算的呢?其实这些东西在top的手册都写的有,首先我们先看一下top中对于CPU使用率的定义,最后的那个单词很关键CPU time
(本文不关注Linux如何对进程的分配CPU时间), kernel会把进程的CPU time写到/proc/{PID}/stat/
这个文件中,。
%CPU -- CPU Usage
The task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.
下面是dockerd进程的数据示例:
1242 (dockerd) S 1 1242 1242 0 -1 1077936384 36414 247979 270 69 7206 4167 806 875 20 0 14 0 1412 1133367296 18712 18446744073709551615 94364227485696 94364275405412 140725279924976 0 0 0 1006249984 0 2143420159 0 0 0 17 1 0 0 92 0 0 94364277503464 94364298771328 94364323065856 140725279932063 140725279932150 140725279932150 140725279932391 0
然后我们写一个很耗CPU的进程,就是死循环啦,它会使某个CPU的使用率达到100%,接受的参数为CPU个数,输出死循环的进程pid,注意在Linux系统中,top显示的CPU使用率和核心数相关,也就是双核的机器最高是200%。
#! /bin/sh
if [ $# != 1 ] ; then
echo "USAGE: $0 <CPUs>"
exit 1;
fi
for i in `seq $1`; do
echo -ne "i=0;while true;do i=i+1;
done" | /bin/sh &
pid_array[$i]=$! ;
done
# 输出pid
for i in "${pid_array[@]}"; do
echo 'kill ' $i ';';
done
根据上面的文档写一个计算CPU使用率的脚本,与top显示的进行对比,计算公式注释已经说明了。
pid=9548
# 输出top计算的与后面进行对比
top -b -n 1 -p $pid 2>&1 | awk -v pid=$pid '{if ($1 == pid)print $9}'
# 找出CPU数目
cpu_core=$(grep -c processor /proc/cpuinfo)
# 0秒时的CPU时间
total_time1=$(awk '{if ($1 == "cpu") {sum = $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9 + $10 + $11;print sum}}' /proc/stat)
cpu_time1=$(awk '{sum=$14 + $15;print sum}' /proc/$pid/stat)
# 1秒后的CPU时间
sleep 1
total_time2=$(awk '{if ($1 == "cpu") {sum = $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9 + $10 + $11;print sum}}' /proc/stat)
cpu_time2=$(awk '{sum=$14 + $15;print sum}' /proc/$pid/stat)
# (进程CPU时间差)处以 系统总CPU时间差 乘以CPU个数
awk -v cpu_time1=$cpu_time1 -v total_time1=$total_time1 -v cpu_time2=$cpu_time2 -v total_time2=$total_time2 -v cpu_core=$cpu_core \
'BEGIN{cpu=((cpu_time2 - cpu_time1) / (total_time2 - total_time1)) * 100*cpu_core;print cpu}'
Memory
对于内存来说经常使用的命令也就是free
,那么它读取的就是这里/proc/meminfo
,例如free命令的输出
free -mh
total used free shared buff/cache available
Mem: 1.9G 212M 133M 956K 1.6G 1.6G
Swap: 0B 0B 0B
其中部分数据如下:
cat /proc/meminfo
MemTotal: 2041120 kB
MemFree: 131632 kB
MemAvailable: 1635632 kB
Buffers: 257304 kB
Cached: 1220788 kB
SwapCached: 0 kB
Active: 914556 kB
Network
对于网络的监控,不仅有网卡的说句,还是TCP UDP等的数据。其中网卡数据主要来源于/proc/net/dev
,
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: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
enp0s3: 655272901 547097 0 0 0 0 0 0 8184738 111064 0 0 0 0 0 0
enp0s8: 38372 393 0 0 0 0 0 2 1846 25 0 0 0 0 0 0
docker0: 210438 4999 0 0 0 0 0 0 25782544 5340 0 0 0 0 0 0
br-4ef817c04403: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
root@ubuntu-bionic:/home/vagrant#
下面是一个通过读取此文件然后输出对应网卡流量的脚本:
#!/bin/bash
usage() {
echo "Useage : $0"
echo "eg. sh $0 eth0 2"
exit 1
}
if [ $# -lt 2 ]
then
usage
fi
eth=$1
timer=$2
in_old=$(cat /proc/net/dev | grep $eth | sed -e "s/\(.*\)\:\(.*\)/\2/g" | awk '{print $1 }')
out_old=$(cat /proc/net/dev | grep $eth | sed -e "s/\(.*\)\:\(.*\)/\2/g" | awk '{print $9 }')
while true
do
sleep ${timer}
in=$(cat /proc/net/dev | grep $eth | sed -e "s/\(.*\)\:\(.*\)/\2/g" | awk '{print $1 }')
out=$(cat /proc/net/dev | grep $eth | sed -e "s/\(.*\)\:\(.*\)/\2/g" | awk '{print $9 }')
dif_in=$(((in-in_old)/timer))
dif_in=$((dif_in/1024))
dif_out=$(((out-out_old)/timer))
dif_out=$((dif_out/1024))
ct=$(date +"%F %H:%M:%S")
echo "${ct} -- IN: ${dif_in} KByte/s OUT: ${dif_out} KByte/s"
in_old=${in}
out_old=${out}
done
exit 0
Ref
CPU使用率原理及计算方式
https://www.cnblogs.com/gatsby123/p/11127158.html
PROCFS AND SYSFS