linux平台关于内存,cpu,连接数,流量监控(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}


程序运行效果




 
 

如有错误请指正:

交流请加QQ群:62054820
QQ:379969650.


猜你喜欢

转载自blog.csdn.net/zhuweigangzwg/article/details/66971357
今日推荐