版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuweigangzwg/article/details/66971357
linux平台关于内存,cpu,连接数,流量监控(一)
本文为监控linux平台机器及进程cpu,内存,连接数,流量监控程序,其他平台请自适应。
//.h
/** Copyright (c/c++) <2017.03.24> <zwg>
* Function
* Monitor the CPU memory connections flow response time program
* 命令:
* 根据名称查看pid :ps aux | grep processname
* 查看cpu内存:ps -o %cpu,rss,%mem,pid,tid -mp pid //watch ifconfig 例如:ps -o %cpu,rss,%mem,pid,tid -mp 108809
* 查看网卡流量:watch more /proc/net/dev
* 查看连接数:netstat -nat|grep -i "port"|wc -l
* 1. 查看物理CPU的个数#cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l
* 2. 查看逻辑CPU的个数#cat /proc/cpuinfo |grep "processor"|wc -l
* 3. 查看CPU是几核#cat /proc/cpuinfo |grep "cores"|uniq
* 4. 查看CPU的主频#cat /proc/cpuinfo |grep MHz|uniq[@more@]
*/
#ifndef __LVS_MONITOR_H__
#define __LVS_MONITOR_H__
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <dirent.h>
#include <sys/time.h>
#include <map>
#include <sys/stat.h>
#include <unistd.h>
#define Printf_INFO //是否输出日志
#define _LINE_LENGTH 300
using namespace std;
class cMonitor;
class cMonitor
{
public:
//构造函数
cMonitor();
//析构函数
virtual ~cMonitor();
//得到逻辑CPU的个数
//参数:
//返回值:逻辑CPU的个数
int GetLogicCpuNum();
//得到cpu使用率内存
//参数: 获取的cpu;mem;传入的pid;tid(可填-1);
//返回值:1 :成功 0 : 失败
int GetCpuMemUsage(float * cpu,int * mem ,const int pid,int tid = -1);
//得到连接数根据port;
//参数: port;
//返回值:连接数
int GetConnectionsByPort(const int port);
//查看网卡流量
//参数: netDeviceName;unBW;nInLB;nOutLB,nInLastBytes是当前上行数据,nInLastBytes是当前下行数据
//返回值:1 :成功 0 : 失败
int GetNetworkTraffic(const string netDeviceName,const unsigned int unBW,const unsigned int nMilisecond,
long * nInLastByte,long * nOutLastByte,unsigned int * nInLB,unsigned int * nOutLB);
//计算固定时间带宽包括上行和下行
//参数: netDeviceName;unBW;nInLB;nOutLB;存储文件句柄pfile;
//返回值:1 :成功 0 : 失败
int GetTimerNetworkTraffic(const string netDeviceName,const unsigned int unBW,const unsigned int nMilisecond,
unsigned int * nInLB,unsigned int * nOutLB,void * pfile);
private:
public:
private:
};
#endif
//.cpp
#include "Monitor.h"
cMonitor::cMonitor()
{
}
cMonitor::~cMonitor()
{
}
int cMonitor::GetLogicCpuNum()
{
char cmdline[100] = {0};
FILE * file = NULL;
char line[_LINE_LENGTH] = {0};
int CpuNum = 0;
//cat /proc/cpuinfo |grep "processor"|wc -l
sprintf(cmdline, "cat /proc/cpuinfo |grep \"processor\"|wc -l");
file = popen(cmdline, "r");
if (file == NULL)
{
#ifdef Printf_INFO
printf("file == NULL\n");
#endif
return 0;
}
if (fgets(line, _LINE_LENGTH, file) != NULL)
{
sscanf(line, "%d", &CpuNum );
}
else
{
//命令错误
#ifdef Printf_INFO
printf("GetLogicCpuNum : Command or Parameter fail\n");
#endif
}
pclose(file);
return CpuNum;
}
int cMonitor::GetCpuMemUsage(float * cpu,int * mem ,const int pid,int tid)
{
int ret = 0;
char cmdline[100] = {0};
FILE * file = NULL;
char line[_LINE_LENGTH] = {0};
float l_cpuPrec = 0.0;
int l_mem = 0;
float l_memPrec = 0;
int l_pid = 0;
int l_tid = 0;
//ps -o %cpu,rss,%mem,pid,tid -mp pid
sprintf(cmdline, "ps -o %%cpu,rss,%%mem,pid,tid -mp %d", pid);
file = popen(cmdline, "r");
if (file == NULL)
{
#ifdef Printf_INFO
printf("file == NULL\n");
#endif
return 0;
}
if (fgets(line, _LINE_LENGTH, file) != NULL) //第一行是 %CPU RSS %MEM PID TID
{
if (fgets(line, _LINE_LENGTH, file) != NULL) //第二行是 0.0 2356 0.0 19736 -
{
sscanf(line, "%f %d %f %d -", &l_cpuPrec, &l_mem, &l_memPrec, &l_pid );
*cpu = l_cpuPrec;
//*mem = l_mem/1024; //具体内存占用情况
*mem = (int )l_memPrec; //内存占用百分比(取整)
if( tid == -1 )
{
ret = 1;
}
else
{
while( fgets(line, _LINE_LENGTH, file) != NULL )
{
sscanf( line, "%f - - - %d", &l_cpuPrec, &l_tid );
if( l_tid == tid )
{
#ifdef Printf_INFO
printf("cpuVal is tid:%d\n",tid);
#endif
*cpu = l_cpuPrec;
ret = 1;
break;
}
}
if( l_tid != tid )
{
//进程 tid 不存在
#ifdef Printf_INFO
printf("TID not exist\n");
#endif
}
}
}
else
{
//进程pid 不存在
#ifdef Printf_INFO
printf("GetCpuMemUsage : PID not exist\n");
#endif
return 0;
}
}
else
{
//命令错误
#ifdef Printf_INFO
printf("GetCpuMemUsage : Command or Parameter fail\n");
#endif
}
pclose(file);
//获取cpu核数
int cpunum = GetLogicCpuNum();
#ifdef Printf_INFO
printf("LogicCpu nuclear : %d\n ",cpunum);
#endif
*cpu = l_cpuPrec/cpunum;
return ret;
}
int cMonitor::GetConnectionsByPort(const int port)
{
char cmdline[100] = {0};
FILE * file = NULL;
char line[_LINE_LENGTH] = {0};
int Connections = 0;
//netstat -nat|grep -i "port"|wc -l
//ps -ef|grep "processname"|wc -l
sprintf(cmdline, "netstat -nat|grep -i \"%d\"|wc -l", port);
file = popen(cmdline, "r");
if (file == NULL)
{
#ifdef Printf_INFO
printf("file == NULL\n");
#endif
return 0;
}
if (fgets(line, _LINE_LENGTH, file) != NULL)
{
sscanf(line, "%d", &Connections);
}
else
{
//进程 port 不存在
#ifdef Printf_INFO
printf("GetConnectionsByPort : port not exist\n");
#endif
}
pclose(file);
return Connections;
}
int cMonitor::GetNetworkTraffic(const string netDeviceName,const unsigned int unBW,const unsigned int nMilisecond,
long * nInLastByte,long * nOutLastByte,unsigned int * nInLB,unsigned int * nOutLB)
{
FILE * fp = NULL;
//watch more /proc/net/dev
fp = fopen("/proc/net/dev","r");
if(fp)
{
char szLine[1024] = {'\0'};
int64_t nR = 0;
int64_t nT = 0;
int n = 0;
while(fgets(szLine,sizeof(szLine),fp))
{
n++;
if(n > 2)
{
char szeth[256] = {'\0'};
sscanf(szLine,"%[^:]",szeth);
printf("GetNetworkTraffic::szeth :%s\n",szeth);
sscanf(szLine+strlen(szeth)+1,"%ld %*u %*u %*u %*u %*u %*u %*u %ld",&nR,&nT);
if((strncasecmp(netDeviceName.c_str(),szeth + 0,netDeviceName.size())==0) ||
(strncasecmp(netDeviceName.c_str(),szeth + 1,netDeviceName.size())==0)||
(strncasecmp(netDeviceName.c_str(),szeth + 2,netDeviceName.size())==0)) //比较字符串前几个字符
{
if((*nInLastByte) == 0 && (*nOutLastByte) == 0)
{
(*nInLastByte) = nR;
(*nOutLastByte) = nT;
fclose(fp);
return 0;
}
int allBW = unBW;
if (nMilisecond == 0 || allBW ==0)
{
(*nInLastByte) = nR;
(*nOutLastByte) = nT;
fclose(fp);
return 0;
}
double fltInTemp = (nR -(*nInLastByte)) * 8.0 /1024; //转换成kbps
double fltOutTemp = (nT - (*nOutLastByte)) * 8.0 /1024;//转换成kbps
float fltInFlow = fltInTemp /(nMilisecond / 1000);//转换成秒的流量
float fltOutFlow = fltOutTemp /(nMilisecond / 1000);//转换成秒的流量
#ifdef Printf_INFO
printf("***************** nR : %ld\n",nR);
printf("***************** nT : %ld\n",nT);
printf("***************** nInLastByte : %ld\n",*nInLastByte);
printf("***************** nOutLastByte : %ld\n",*nOutLastByte);
printf("***************** fltInTemp : %lf\n",fltInTemp);
printf("***************** fltOutTemp : %lf\n",fltOutTemp);
#endif
*nInLB = (unsigned int)(fltInFlow);
*nOutLB = (unsigned int)(fltOutFlow);
(*nInLastByte) = nR;
(*nOutLastByte) = nT;
break;
}
else
{
printf("netDeviceName error\n");
}
}
}
fclose(fp);
}
else
{
#ifdef Printf_INFO
printf("open /proc/net/dev file fail\n");
#endif
return 0;
}
return 1;
}
int cMonitor::GetTimerNetworkTraffic(const string netDeviceName,const unsigned int unBW,const unsigned int nMilisecond,
unsigned int * nInLB,unsigned int * nOutLB,void * pfile)
{
int ret = 0;
long nInLastByte = 0; //流量用获取第二次流量减去获取第一次流量
long nOutLastByte = 0; //流量用获取第二次流量减去获取第一次流量
struct timeval tv_begin; //当前时间起始
struct timeval tv_end; //当前时间结束
//获取开始时间
gettimeofday(&tv_begin,NULL);
//第一次获取带宽的数值
GetNetworkTraffic(netDeviceName,unBW,nMilisecond,
&nInLastByte,&nOutLastByte,nInLB,nOutLB);
printf("nInLastByte %ld nOutLastByte :%ld\n",nInLastByte,nOutLastByte);
while(1)
{
//获取结束时间
gettimeofday(&tv_end,NULL);
int nDeff = ((tv_begin.tv_sec - tv_end.tv_sec) * 1000000 + (tv_begin.tv_usec - tv_end.tv_usec) ) / 1000000; //转化成微妙
if (nDeff > nMilisecond *1000)
{
//第二次获取带宽的数值
GetNetworkTraffic(netDeviceName,unBW,nMilisecond,
&nInLastByte, &nOutLastByte,nInLB,nOutLB);
printf("nInLastByte %ld nOutLastByte :%ld\n",nInLastByte,nOutLastByte);
break;
}
else
{
usleep(1000);
continue;
}
}
//写到文件中
if (pfile != NULL)
{
char fileinfo[256] = {0};
sprintf(fileinfo,"netDeviceName :%s unBW :%dM time : %dms nInLB : %uKbps nOutLB : %uKbps\n",
netDeviceName.c_str(),unBW,nMilisecond,*nInLB,*nOutLB);
int writesize = fwrite(fileinfo, strlen(fileinfo), 1, (FILE *)pfile);
fflush((FILE *)pfile);
}
return ret;
}
//main.cpp
//下面是测试
int main()
{
cMonitor *pmonitor = new cMonitor();
//step1 测试cpu 内存
float ncpu = 0.0; //cpu
int nmem = 0; //内存
int npid = 0; //pid
int ntid = -1; //tid
npid = 108809;
pmonitor->GetCpuMemUsage(&ncpu,&nmem,npid,ntid);
printf("Pid : %d %%CPU:%.1f\tMEM:%d\n",npid,ncpu ,nmem);
//step2 测试连接数
int nport = 0;
int connectnum = 0;
nport = 1936;
connectnum = pmonitor->GetConnectionsByPort(nport);
printf("nport: %d connectnum : %d\n",nport,connectnum);
//step3 测试带宽网卡流量
string netDeviceName = "eth2"; //网卡设备号
//string netDeviceName = "enp0s31f6"; //网卡设备号
int unBW = 0; //设置带宽最大值(M)
unsigned int nInLB = 0; //上行流量
unsigned int nOutLB = 0; //下行流量
long long nInLB_all = 0; //上行流量总值
long long nOutLB_all = 0; //下行流量总值
long long nLB_timer = 0; //流量总共时间
unsigned int nMilisecond = 0; //毫秒数
nMilisecond = 1000; //1秒
unBW = 500; //500m
FILE * pnetworkfp = NULL; //存储带宽的
pnetworkfp = fopen("network.log","wb");
//持续获取流量信息
#if 1
while(1)
{
pmonitor->GetTimerNetworkTraffic(netDeviceName,unBW,nMilisecond,
&nInLB,&nOutLB,pnetworkfp);
printf("netDeviceName :%s unBW :%dM time : %dms nInLB : %uKbps nOutLB : %uKbps\n",
netDeviceName.c_str(),unBW,nMilisecond,nInLB,nOutLB);
nInLB_all += nInLB;
nOutLB_all += nOutLB;
nLB_timer += nMilisecond;
printf("****************Average LB : in : %dKbps out : %dKbps\n",nInLB_all/(nLB_timer/nMilisecond),nOutLB_all/(nLB_timer/nMilisecond));
};
#else
pmonitor->GetTimerNetworkTraffic(netDeviceName,unBW,nMilisecond,
&nInLB,&nOutLB,pnetworkfp);
printf("netDeviceName :%s unBW :%dM time : %dms nInLB : %uKbps nOutLB : %uKbps\n",
netDeviceName.c_str(),unBW,nMilisecond,nInLB,nOutLB);
#endif
//关闭文件
if (pnetworkfp)
{
fclose(pnetworkfp);
pnetworkfp = NULL;
}
delete pmonitor;
pmonitor = NULL;
}
程序运行效果
如有错误请指正: