23,124
社区成员
发帖
与我相关
我的任务
分享
#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);
}
#define _GNU_SOURCE
#include <stdio.h>
//获取网卡吞吐率
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;
}