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

来源:互联网 发布:java http请求获取mac 编辑:程序博客网 时间:2024/05/23 19:01

一、说明:

       之前在做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}')
        T
otal_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


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



       


原创粉丝点击