注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Fly to the Sky!

很多人因为寂寞而错爱一个人,更多人因为错爱一个人而寂寞一生。

 
 
 

日志

 
 

通过proc文件系统获取系统性能监测参数-代码实现 [转]  

2009-08-10 14:40:23|  分类: 性能测试 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
                               
#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>
//打印调试信息
#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;
//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;
//网卡流量
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; irlim.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;
    if(szLine)
        free(szLine);
    if(fp)
        fclose(fp);
}
//获取网卡吞吐率
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();
    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 );
}
//参考cron实现
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;
    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();
    return 0;
}
                
               

  评论这张
 
阅读(914)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018