Linux系统资源获取并写入数据库

xiaoxiao2021-02-28  108

一、说明:

       之前在做srs流媒体压测时,系统资源相关的数据查看不方便,于是就使用C++ 加上shell脚本,实时获取Linux系统资源情况并将数据写入到数据库中。

二、脚本目录介绍:

     流媒体服务器(172.18.152.*3)

     脚本目录介绍:      /root/GetSystemInfo    //脚本目录      GetSystemInfo.cpp      //主程序      cpurate.sh                   //获取cpu使用率      getsize.sh                    //获取磁盘空间      memrate.sh                 //获取内存使用率      network_recev.sh        //获取网络接收流量      network_send.sh         //获取网络发送流量      getonline.sh                //获取在线个数      runtest.sh                    //编译并运行主程序

     推流端(172.18.152.*6)

     脚本目录介绍:      /root/                                //目录      kill_rtmp_pid.cpp              //调用GetPidAndKill.sh脚本      GetPidAndKill.sh               //获取pid并杀掉      rtmp_publish_test.sh        //开始推流脚本      runtest.sh                         //编译并运行kill_rtmp_pid.cpp

     拉流端(172.18.151.*4)  

     脚本目录介绍:      /root/                                //目录      kill_rtmp_pid.cpp              //调用GetPidAndKill.sh脚本      GetPidAndKill.sh               //获取pid并杀掉      rtmp_load_test.sh             //开始拉流脚本      runtest.sh                         //编译并运行kill_rtmp_pid.cpp

三、系统资源的获取

        1、  cpu使用率获取:         原理是读取系统的 (/proc/stat)文件,然后再提取出想要的数据,再对其进行计算,如图:

        

     

第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下面对各项参数进行解释说明:

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

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

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

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

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

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

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

“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。

“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。

“btime”给出了从系统启动到现在为止的时间,单位为秒。

“processes (total_forks) 自系统启动以来所创建的任务的个数目。

“procs_running”:当前运行队列的任务的数目。

“procs_blocked”:当前被阻塞的任务的数目。

CPU利用率计算公式:

CPU时间=user+system+nice+idle+iowait+irq+softirq

先取两个采样点,然后计算其差值: cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100

下面开始使用shell脚本来获取,脚本如下:

        #!/bin/sh

        CPULOG_1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')         SYS_IDLE_1=$(echo $CPULOG_1 | awk '{print $4}')         Total_1=$(echo $CPULOG_1 | awk '{print $1+$2+$3+$4+$5+$6+$7}')

        sleep 1

        CPULOG_2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')         SYS_IDLE_2=$(echo $CPULOG_2 | awk '{print $4}')         Total_2=$(echo $CPULOG_2 | awk '{print $1+$2+$3+$4+$5+$6+$7}')

        SYS_IDLE=`expr $SYS_IDLE_2 - $SYS_IDLE_1`

        Total=`expr $Total_2 - $Total_1`         SYS_USAGE=`expr $SYS_IDLE/$Total*100 |bc -l`

        SYS_Rate=`expr 100-$SYS_USAGE |bc -l`

        Disp_SYS_Rate=`expr "scale=3; a=$SYS_Rate/1;  if(length(a)==scale(a) && a!=0) print 0;print a" |bc`         echo $Disp_SYS_Rate%

       2、内存使用率获取:

        原理是读取系统的 (/proc/meminfo)文件,然后再提取出想要的数据,再对其进行计算,脚本如下:

        #!/bin/sh

        MemTotal=$(cat /proc/meminfo | grep 'MemTotal' | awk '{print $2}')         MemFree=$(cat /proc/meminfo | grep 'MemFree' | awk '{print $2}')         Disp_SYS_Rate=`expr "scale=3; a=100*$MemFree/$MemTotal;  if(length(a)==scale(a)) print 0;print a" |bc`         echo $MemTotal         echo $MemFree         echo $Disp_SYS_Rate%

      

        3、网络流量获取:

         原理是读取系统的 (/proc/net/dev)文件,然后再提取出想要的数据,再对其进行计算,得出上行速率:

         接收(recev):

         #!/bin/sh           

         cat /proc/net/dev | grep 'enp4s0' | awk '{ if($2!=0) print $2}

        

          发送(send):

          #!/bin/sh

          cat /proc/net/dev | grep 'enp4s0' | awk '{ if($2!=0) print $10/(1024*1024)}'

    

         4、磁盘空间使用率获取:

          原理是通过(df -h)命令得到系统磁盘使用情况,然后再提取出想要的数据

           #!/bin/bash

           LISTEN_PATH=./            if [ -n $1 ]; then            LISTEN_PATH=$1            fi            echo `df -h $LISTEN_PATH | grep "dev" `| awk '{print $3"/"$2}'

          磁盘空间使用情况如下:

四、实现:

  下面就以获取CPU使用率为例,其他资源的获取也类似:

1、第一步:使用C++代码获取到CPU使用率

    //获取Cpu使用率    bool GetCpuRate(std::string& cpurate)    {     FILE *file;     string cmd("./cpurate.sh");

    file = popen(cmd.c_str(), "r");     if(file == NULL)     {         cout<<cmd<<" fail"<<endl;         return false;     }     char buf[512] = {0};

    while(fgets(buf, sizeof(buf), file) != NULL)     {         char tmpbuf[512]={0};         sscanf(buf,"%s",tmpbuf);         cpurate=std::string(tmpbuf);     }     pclose(file);     return true; }

2、第二步:将获取CPU的值,写入到数据库:

//连接数据库 if(!mysql_real_connect(&mysql, "localhost", "root", "123456", "srs_linux_systeminfo", 0, NULL, 0)) {           printf("Failed to connect to Mysql!\n");   log_out << "Failed to connect to Mysql!" <<  endl;         return 0;       }else {           printf("Connected to Mysql successfully!\n");   log_out<<"Connected to Mysql successfully!"<<endl;     }  

//创建数据库表(以系统当前时间为表名)         char sqlstr[100]; int create_table_flag; string TableName=systime; sprintf(sqlstr,"create table if not exists SRS_Linux_SystemInfo_%s(Id int(32),Time char(60),OnlineCount char(60),CpuRate char(60),MemRate char(60),Network_Recev_Rate char(60),Network_Send_Rate char(60),Network_Recev_Traffic char(60),Network_Send_Traffic char(60),DiskInfo char(60))",TableName.c_str()); create_table_flag=mysql_real_query(&mysql,sqlstr,strlen(sqlstr)); if(create_table_flag) { printf("create table fail!\n");   log_out<<"create table fail!"<<endl;         return 0; }else {           printf("create table success!\n");  log_out<<"create table success!"<<endl;     }  

//插入数据库数据     char sql[300];  sprintf(sql,"insert into SRS_Linux_SystemInfo_%s(Id, Time,OnlineCount, CpuRate, MemRate, Network_Recev_Rate,Network_Send_Rate,Network_Recev_Traffic,Network_Send_Traffic ,DiskInfo) values('%d','%ds','%s','%s','%s','%dKB','%dKB','%sMB','%sMB','%s') ",TableName.c_str(),i,(Interval_TIME*i),onlinecount.c_str(),cpurate.c_str(),memrate.c_str(),(rx_rate/1024/PushClient),(tx_rate/1024/PullClient),network_recev.c_str(),network_send.c_str(),diskInfo.c_str());  flag=mysql_real_query(&mysql,sql,strlen(sql));      if(flag) {           printf("Insert data failure!\n");           return 0;       }else {           printf("Insert data success!\n");       }  

备注:

Linux编译C++ 脚本命令:

        g++ -o getsysteminfo GetSystemInfo.cpp $(mysql_config --libs)        ./getsysteminfo

五、定时执行shell脚本和C++代码:

     crontab定时执行脚本:

      步骤如下:       1.编辑crontab服务文件,命令如下:           crontab -e          2.输入如下内容,每天晚上定时九点开始执行脚本:                       30 21 * * * /root/runcpptest.sh       3.使用命令查看是否添加成功:         crontab -l       4.重启crontab服务生效:         /bin/systemctl restart  crond.service

最后来看看实现的效果图:

       

转载请注明原文地址: https://www.6miu.com/read-18950.html

最新回复(0)