Objective
The previous time because of the project needs, need to obtain the current operating state of the system in real time, then consulted a lot of information, based on the/proc directory of some files, to achieve the system CPU, memory, network and disk real-time monitoring.
First, CPU usage gets
Get CPU usage is obtained from the/proc/stat file,/proc/stat contains many statistics about kernel and the system since the start of the system, including CPU running, interrupt statistics, startup time, Context switch times, running processes, and so on.
CPU 1149770 0 309685 239871041 7 0 0 0cpu0 1149770 0 309685 239871041 7 0 0 0intr 0swap 0 0ctxt 892809418btime 1525518 899processes 379246procs_running 1procs_blocked 0
The "CPU" line shows the time of all CPUs on USER-SAPCE, kernel mode, followed by the statistics of each CPU.
The "Intr" line shows the information about the system interruption, the first is the number of interrupts that have occurred since the system started, and then each number corresponds to the number of times that a particular interrupt has occurred since the system started.
The number of interrupts that have occurred since the system started.
The "Ctxt" line shows the number of context exchanges that have occurred on the CPU since the system started.
The "Btime" line shows the time from the system boot up to now (in epoch time, 1970-01-01 00:00:00 +0000 (UTC)), in seconds.
The "Processes" line shows the number of tasks created since the system started (Total_forks).
The "procs_running" line shows the number of tasks that are currently running the queue.
The "procs_blocked" line shows the number of tasks that are currently blocked.
To calculate the CPU occupancy, just focus on the first line, each parameter has the following meanings:
User |
From the beginning of the system start up to the current moment, the user-state CPU time, does not contain the nice value for a negative process. |
Nice |
The CPU time occupied by a process that has a negative nice value from the beginning of the system startup to the current moment |
System |
Accumulated from the start of the system to the current time, the core time |
Idle |
Accumulate from the start of the system to the current moment, waiting time other than IO wait time |
Iowait |
Accumulate from the start of the system to the current time, IO wait time |
Irq |
Accumulated from the start of the system to the current moment, hard interrupt Time |
Softirq |
Accumulated from the start of the system to the current moment, soft interrupt time |
Because the values in the/proc/stat are accumulated from the start of the system to the current time, it is necessary to compare the values of T1 and T2 at different points in time, and when the interval of two points is shorter (i take 1s), the result can be considered as the CPU's immediate utilization.
Calculation formula for the immediate utilization of the CPU:
Total usage time of CPU in T1 to t2 period = (user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2)-(user1+ nice1+ system1+ idle1+ iowait1+ I rq1+ softirq1)
CPU idle time in T1 to t2 period = (idle2-idle1)
CPU in T1 to T2 time period instant utilization = 1-CPU idle use time/CPU total usage time
Source
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), 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 su B2 = cpuinfo2.idle;double cpu_use;if ((sub1-sub2)! = 0) Cpu_use = 100.0-((SUB2-SUB1)/(INFO2D-INFO1D)) * 100.0;els Ecpu_use = 0;//double Cpu_use = Cpuinfo1.user/info1d;return cpu_use;}
Second, memory use situation
Memory usage is obtained from the/proc/meminfo file.
[Root ~]# cat/proc/meminfomemtotal: 1048576 kbmemfree: 927940 kbcached: 31468 kbbuffers: 0 kbactive: 46764 kbinactive: 50516 kbactive (anon): 32312 kbinactive (anon): 33500 kbactive (file): 14452 Kbinactive (file): 17016 kbunevictable: 0 kbmlocked: 0 kbswaptotal: 131072 kbswapfree: 86620 kbdirty: kbwriteback: 0 kbanonpages: 65812 kbshmem: 164 kbslab : 23172 Kbsreclaimable: 6552 kbsunreclaim: 16620 KB
The focus here is on Memtotal, Memfree, and Cached three values, memory in use = 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); 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 ();}
Third, the network transmission (upload and download speed)
Network usage is obtained from the/proc/net/dev file.
[Root ~]# cat/proc/net/devinter-| 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 0venet0:21610450920 22790055 0 0 0 0 0 0 22011662266 22005133 0 148 0 0 0 0
The network upload and download speed is calculated based on the number of bytes received in the NIC venet0 unit time (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 ());d owns = 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);}
Four, the use of hard disk
Hard disk usage is divided into two parts: hard disk space usage and hard disk real-time reading and writing.
The use of the hard disk can be obtained through the STATFS () function, the reading and writing speed is calculated by the number of sectors read and write within the unit time (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 RAM10 0 0 0 0 0 0 0 0 0 0 0 1 one ram11 0 0 0 0 0 0 0 0 0 0 0 1 ram12 0 0 0 0 0 0 0 0 0 0 0 1 ram13 0 0 0 0 0 0 0 0 0 0 0 1 ram14 0 0 0 0 0 0 0 0 0 0 0 1 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 181148 5376 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.subst R (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);d iskinfo.read_speed = (reads2-reads1) * disk.f_bsize;diskinfo.write_speed = (writes2-writes1) * disk.f_bsize;}
The full code is detailed in my gihub.
Building blocks: Linux system monitoring