通过proc文件系统获取系统性能监测参数

atiansk2006 2009-05-13 09:13:42
下面的代码是从网上down到, 然后自己修改了下, 想把统计到的结果输出文件中,但得到结果是空文件,帮忙看一下那里操作的有问题了?


#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/resource.h>

#include <unistd.h>

#include <fcntl.h>

#include <syslog.h>

#include <time.h>

#include <math.h>

#include <stdlib.h>

#include <string.h>





//打印调试信息

#define DBG_print(level, lpszFormat, ...) \

syslog(level|LOG_DAEMON, lpszFormat, ##__VA_ARGS__)



//发送性能日志信息

#define LOG_print(lpszFormat, ...) \

syslog(LOG_INFO, lpszFormat, ##__VA_ARGS__)



//用于时间同步

time_t TargetTime;



FILE *fpResult;



//CPU使用

unsigned long long cpu_total = 0;

unsigned long long cpu_total_used = 0;

unsigned long long pre_cpu_total = 0;

unsigned long long pre_cpu_total_used = 0;

int cpu_percent_used = 0;



//内存

int mem_total = 0;

int mem_free = 0;

int mem_percent_used = 0;



//网卡流量

unsigned long long eth0_in = 0;

unsigned long long eth0_out = 0;

unsigned long long eth1_in = 0;

unsigned long long eth1_out = 0;

unsigned long long pre_eth0_in = 0;

unsigned long long pre_eth0_out = 0;

unsigned long long pre_eth1_in = 0;

unsigned long long pre_eth1_out = 0;

time_t pre_time = 0;

int eth0_in_bps = 0;

int eth0_out_bps = 0;

int eth1_in_bps = 0;

int eth1_out_bps = 0;



//并发tcp连接数

#define MAX_CONN 40960

typedef enum {

TCP_ESTABLISHED = 1,

TCP_SYN_SENT,

TCP_SYN_RECV,

TCP_FIN_WAIT1,

TCP_FIN_WAIT2,

TCP_TIME_WAIT,

TCP_CLOSE,

TCP_CLOSE_WAIT,

TCP_LAST_ACK,

TCP_LISTEN

} TCP_STATE;

struct TCP_CONN {

TCP_STATE st;

unsigned long local_ip;

unsigned long local_port;

unsigned long remote_ip;

unsigned long remote_port;

} tcp_conns[MAX_CONN];

int nTcpConns = 0;



int daemon_init()

{

pid_t pid;

struct rlimit rlim;

int i;





if( (pid=fork()) < 0 )

return -1;

else if( pid != 0 )

exit(0);



//child continues

setsid();

chdir("/");

umask(0);

// 关闭所有文件描述符号

getrlimit( RLIMIT_NOFILE, &rlim );

for( i = 0; i<rlim.rlim_cur; i++ ) {

close(i);

}



return 0;

}



//获取CPU使用率

void run_cpu()

{

FILE *fp = NULL;

char *szLine = NULL;

size_t len = 0;



unsigned long long normal_user = 0;

unsigned long long nice_user = 0;

unsigned long long system = 0;

unsigned long long idle = 0;

unsigned long long iowait = 0;

unsigned long long irq = 0;

unsigned long long softirq = 0;



fp = fopen("/proc/stat", "r");

if( fp == NULL ) {

DBG_print(LOG_ERR, "run_cpu: open /proc/stat error");

return;

}



if( getline(&szLine, &len, fp) < 0 ) {

DBG_print(LOG_ERR, "run_cpu: read /proc/stat error");

fclose(fp);

return;

}



sscanf(szLine, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",

&normal_user, &nice_user,

&system, &idle,

&iowait, &irq, &softirq );



//更新全局变量

pre_cpu_total = cpu_total;

pre_cpu_total_used = cpu_total_used;

cpu_total_used = normal_user + nice_user + system + iowait + irq + softirq;

cpu_total = idle + cpu_total_used;



//计算CPU使用率,这是前一个时间间隔内的平均使用率

cpu_percent_used = (int)

ceil( 100 * ((float)(cpu_total_used-pre_cpu_total_used)) / (cpu_total-pre_cpu_total) );



if(szLine)

free(szLine);

if(fp)

fclose(fp);

}



//获取内存使用信息

void run_memory()

{

FILE *fp = NULL;

char *szLine = NULL;

size_t len = 0;



int nTotal = 0;

int nFree = 0;

int nBuffers = 0;

int nCached = 0;

int nSwapCached = 0;



fp = fopen("/proc/meminfo", "r");

if( fp == NULL ) {

DBG_print(LOG_ERR, "run_memory: open /proc/meminfo error");

return;

}



while(!feof(fp)) {

if(szLine) {

free(szLine);

szLine = NULL;

}





if( getline(&szLine, &len, fp) < 0 ) {

if(feof(fp))

continue;

DBG_print(LOG_ERR, "run_memory: read /proc/meminfo error");

fclose(fp);

return;

}



if( strncmp(szLine, "MemTotal", strlen("MemTotal")) == 0 ) {

sscanf(szLine, "MemTotal: %d", &nTotal);

}

else if( strncmp(szLine, "MemFree", strlen("MemFree")) == 0 ) {

sscanf(szLine, "MemFree: %d", &nFree);

}

else if( strncmp(szLine, "Buffers", strlen("Buffers")) == 0 ) {

sscanf(szLine, "Buffers: %d", &nBuffers);

}

else if( strncmp(szLine, "Cached", strlen("Cached")) == 0 ) {

sscanf(szLine, "Cached: %d", &nCached);

}

else if( strncmp(szLine, "SwapCached", strlen("SwapCached")) == 0 ) {

sscanf(szLine, "SwapCached: %d", &nSwapCached);

break;

}

else

continue;

}



//更新

mem_total = nTotal;

mem_free = nFree + nBuffers + nCached + nSwapCached;

mem_percent_used = (int)ceil(100*((float)(mem_total-mem_free)/mem_total));



if(szLine)

free(szLine);

if(fp)

fclose(fp);

}







...全文
297 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
mark
threeleafzerg007 2009-05-14
  • 打赏
  • 举报
回复
同楼上


//打印调试信息

#define DBG_print(level, lpszFormat, ...) \

syslog(level|LOG_DAEMON, lpszFormat, ##__VA_ARGS__)



//发送性能日志信息

#define LOG_print(lpszFormat, ...) \

syslog(LOG_INFO, lpszFormat, ##__VA_ARGS__)

你用syslog看日志,当然不太可能 从stdout能看出东西

看一下syslog.conf文件具体打到哪里去了
atiansk2006 2009-05-14
  • 打赏
  • 举报
回复


看了代码, 知道是怎么操作了, 谢谢源码的作者(在网上找到的不知道谁写的), 我分开写了三个程序, 分别运行都可以正确统计, 然后剩下的工作就是把它们整合到一块去.




morris88 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 atiansk2006 的回复:]
是的, /var/log/messages里面有输出, 我想让结果打印到我建的文件中去. 结果print不到我的文件中.
[/Quote]

那么可以不用 syslog 嘛,直接 fprintf() 就可以打印到你指定的文件中了嘛...
atiansk2006 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 morris88 的回复:]
先要加上一个宏定义:

C/C++ code#define _GNU_SOURCE
#include <stdio.h>


输出一般在 /var/log/messages ...
[/Quote]





是的, /var/log/messages里面有输出, 我想让结果打印到我建的文件中去. 结果print不到我的文件中.

morris88 2009-05-13
  • 打赏
  • 举报
回复
先要加上一个宏定义:
#define	_GNU_SOURCE
#include <stdio.h>

输出一般在 /var/log/messages ...
  • 打赏
  • 举报
回复
有点晕,这么长
嗨皮 2009-05-13
  • 打赏
  • 举报
回复
加点printf调试一下就出来了。
atiansk2006 2009-05-13
  • 打赏
  • 举报
回复
thanks in advance.
atiansk2006 2009-05-13
  • 打赏
  • 举报
回复


//获取网卡吞吐率

void run_throughput()

{

FILE *fp = NULL;

char *szLine = NULL;

size_t len = 0;



unsigned long long nEth0In = 0;

unsigned long long nEth0Out = 0;

unsigned long long nEth1In = 0;

unsigned long long nEth1Out = 0;

unsigned long long nouse = 0;



time_t now;

int nSeconds = 0;



fp = fopen("/proc/net/dev", "r");

if( fp == NULL ) {

DBG_print(LOG_ERR, "run_throughput: open /proc/net/dev error");

return;

}



while(!feof(fp)) {

int i = 0;

char *p = NULL;





if(szLine) {

free(szLine);

szLine = NULL;

}

if( getline(&szLine, &len, fp) < 0 ) {

if(feof(fp))

continue;

DBG_print(LOG_ERR, "run_throughput: read /proc/net/dev error");

fclose(fp);

return;

}



//忽略每行开头的空格

p = szLine;

while( *p && (*p==' ') )

p++;



if( strncmp(p, "eth0", strlen("eth0")) == 0 ) {

sscanf(p, "eth0:%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",

&nEth0In,

&nouse, &nouse, &nouse, &nouse, &nouse, &nouse, &nouse,

&nEth0Out );

}

else if( strncmp(p, "eth1", strlen("eth1")) == 0 ) {

sscanf(p, "eth1:%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",

&nEth1In,

&nouse, &nouse, &nouse, &nouse, &nouse, &nouse, &nouse,

&nEth1Out );

break;

}

else

continue;

}



//更新全局变量

pre_eth0_in = eth0_in;

pre_eth0_out = eth0_out;

pre_eth1_in = eth1_in;

pre_eth1_out = eth1_out;



eth0_in = nEth0In;

eth0_out = nEth0Out;

eth1_in = nEth1In;

eth1_out = nEth1Out;



//计算时间间隔

now = time((time_t*)0);

nSeconds = now-pre_time;

pre_time = now;



//计算网卡流速

eth0_in_bps = (int) ( (eth0_in-pre_eth0_in) / nSeconds );

eth0_out_bps = (int) ( (eth0_out-pre_eth0_out) / nSeconds );

eth1_in_bps = (int) ( (eth1_in-pre_eth1_in) / nSeconds );

eth1_out_bps = (int) ( (eth1_out-pre_eth1_out) / nSeconds );



if(szLine)

free(szLine);

if(fp)

fclose(fp);

}



//获取tcp连接数

void run_tcpconn()

{

FILE *fp = NULL;

char *szLine = NULL;

size_t len = 0;



int i;

int nID;



struct TCP_CONN *conn = NULL;



fp = fopen("/proc/net/tcp", "r");

if( fp == NULL ) {

DBG_print(LOG_ERR, "run_tcpconn: open /proc/net/tcp error");

return;

}



conn = tcp_conns;

while(!feof(fp)) {

char *p = NULL;

if(szLine) {

free(szLine);

szLine = NULL;

}

if( getline(&szLine, &len, fp) < 0 ) {

if(feof(fp))

continue;

DBG_print(LOG_ERR, "run_tcpconn: read /proc/net/tcp error");

fclose(fp);

return;

}



p = szLine;

while( *p && (*p==' ') )

p++;



//除sl开头的行,其余每行都是一个tcp连接

if( strncmp(p, "sl", strlen("sl")) ) {

sscanf(p, "%d:%x:%x %x:%x %x",

&nID,

&(conn->local_ip), &(conn->local_port),

&(conn->remote_ip), &(conn->remote_port),

&(conn->st) );

conn++;

}

else

continue;

}



conn->st = 0;

conn = tcp_conns;

nTcpConns = 0;

while(conn->st) {

if(conn->st != TCP_LISTEN) {

nTcpConns++;

}

conn++;

}



if(szLine)

free(szLine);

if(fp)

fclose(fp);

}



int job_run()

{

run_cpu();

run_memory();

run_throughput();

run_tcpconn();

char tmp_buffer[256];



LOG_print("%d,%d,%d,%d,%d,%d,%d,%d",

cpu_percent_used,

mem_total, mem_free,

eth0_in_bps, eth0_out_bps,

eth1_in_bps, eth1_out_bps,

nTcpConns );



fpResult = fopen ("/home/statistics", "a+");





fprintf (fpResult, "***********************************************************\n");



fprintf (fpResult, "CPU: %d \%\n\nMemory Total: %d\nMemory Free: %d\nMemory: %d \%\n\neth0 in:%d\neth0 out:%d\n\neth1 in%d\neth1 out%d\n\nTCP Conns%d\n", cpu_percent_used, mem_total, mem_free, mem_percent_used, eth0_in_bps, eth0_out_bps, eth1_in_bps, eth1_out_bps, nTcpConns);



fputs ("###########################################################\n", fpResult);

}





static void sysstat_sync() {

struct tm *tm;

TargetTime = time((time_t*)0);

tm = localtime(&TargetTime);

TargetTime += (60 - tm->tm_sec);

}



//参考cron实现

static void sysstat_sleep() {

int seconds_to_wait;

seconds_to_wait = (int) (TargetTime - time((time_t*)0));

while (seconds_to_wait > 0) {

seconds_to_wait = (int) sleep((unsigned int) seconds_to_wait);

}

}





int main()



{

int nInterval = 60;

time_t now;





fpResult = fopen ("/home/statistics", "a+");

if (!fpResult)

DBG_print(LOG_DEBUG, "open /home/statistics fail !!!\n");



daemon_init();



openlog("RESOURCE", LOG_NDELAY|LOG_CONS|LOG_PID, LOG_USER);



now = time((time_t*)0);

DBG_print(LOG_DEBUG, "start at %s", ctime(&now));





sysstat_sync();



while(1) {

sysstat_sleep();





now = time((time_t*)0);

DBG_print(LOG_DEBUG, "run job at %s", ctime(&now));





job_run();

do{

TargetTime += nInterval;

} while(TargetTime < time((time_t*)0));

}



now = time((time_t*)0);

DBG_print(LOG_DEBUG, "stop at %s", ctime(&now));



closelog();



if (fpResult)

fclose (fpResult);

return 0;

}

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧