作者:李宇 流量统计 流量统计使用ntop提供的统计功能来实现。ntop在统计过程中,会在内存中创建一个数据列表,即时更新数据信息。同时,它提供定时向数据库中发送相关数据的功能,时间间隔可以在编译前设置。我们可以根据实际需要定义ntop统计的数据。利用ntop提供的向mysql数据库中更新数据的方法,定期存储数据到备份数据库表中。定期存储数据的功能使用select _test.c实现,同时刷新内存中ntop流量值及ntop默认数据库表。 有了保存于MySQL数据库中的统计数据,通过来用PHP编写动态网页,完成数据库中数据的查询和统计。具体的实现方法比较简单。如果需要了解如何构建Apache+MySQL+PHP完成流量查询,可以在很多Linux技术交流网站查找到相关的技术文档。 由于ntop记录的信息非常详细,有些协议是很少使用的,或是产生的流量比较少,可以忽略不计,所以我们要对ntop记录的数据做一调整。 以下所做的工作有简化数据表结构(保留我们需要的字段,简化保存的数据);创建备份数据库表test;修改ntop源代码中的sql.c,简化默认的ntop向MySQL数据库中添加的数据;编写数据库表数据的备份程序;设定ntop对数据库的刷新时间,保证刷新内存的时间小于我们设定的循环时间(参见ntop.h);将网卡设置为非混杂模式;编写脚本完成循环统计功能。 简化后的数据表结构(mySQLdefs.txt) CREATE TABLE IPtraffic ( IPaddress CHAR(16) NOT NULL, TCPsentRemotely INT, TCPrcvdFromRemote INT, UDPsentRemotely INT, UDPrcvdFromRemote INT, PRIMARY KEY (IPaddress) ); CREATE TABLE NameMapper ( IPaddress CHAR(16) NOT NULL, Name CHAR(50), PRIMARY KEY (IPaddress) ); 创建备份数据库表test Field Type Null Key Default Extra IPaddress varchar(20) YES NULL data int(11) YES NULL dates date YES NULL 修改ntop源代码中的sql.c 例如: if(snprintf(sqlBuf, SQL_BUF_LEN, "UPDATE IPtraffic SET " "TCPSentRemotely = %llu," "TCPrcvdFromRemote = %llu," "UDPSentRemotely = %llu," "UDPrcvdFromRemote = %llu" "WHERE IPaddress = '%s'", (el->tcpSentRemotely), (el->tcpReceivedFromRemote), (el->udpSentRemotely), (el->udpReceivedFromRemote), el->hostNumIpAddress) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!"); sendto(sqlSocket, sqlBuf, strlen(sqlBuf), 0, (strUCt sockaddr *)&dest, sizeof(dest)); 将需要的字段保留,其它的去除! 编写数据库表数据的备份程序select_test.c的编译程序(编译时运行make) Makefile : #This is a Makefile for select_test.c CC = gcc INCLUDE = -I/usr/include/mysql LIBPATH = -L/usr/lib/mysql LLIB = -lmysqlclient select_test:select_test.c $(CC) -o select_test select_test.c $(INCLUDE) $(LIBPATH) $(LLIB) 数据库表数据备份程序select_test.c: #include #include #include "mysql.h" #include #include #define SELECT_QUERY "select IPaddress,(UDPrcvdFromRemote+UDPsentRemotely+TCPrcv dFromRemote+TCPsentRemotely) as data from IPtraffic where IPaddress like \"%s\" or IPaddress like \"%s\"" #define INSERT_QUERY "insert into test (IPaddress,data,dates) values (\"%s\",%d,\"%s\")" #define TEST_QUERY "select dates from test where dates=\"%s\"" /*获取当前日期*/ getdates(char *currentdate) { struct timeval datetemp; struct tm * datetemp1; gettimeofday(&datetemp,(void *)NULL); datetemp1 = localtime(&(datetemp.tv_sec)); sprintf(currentdate,"%d-%02d-%02d",datetemp1->tm_year+1900,datetemp1->tm_mon+1, datetemp1->tm_mday); } int main(int argc, char **argv) { unsigned int num_fields; unsigned int i; int count,num,charge; MYSQL mysql,*sock; MYSQL_RES *res; MYSQL_FIELD **fields; MYSQL_ROW row; char selectqbuf[1024]; char insertqbuf[1024]; char testqbuf[512]; char currentdate[11]; currentdate[10] = 0; if (argc != 3) { fprintf(stderr,"usage : select_test \n\n");#设定需要统计的网段 exit(1); } mysql_init(&mysql); if (!(sock= mysql_real_connect(&mysql,NULL,0,0,"NTOP",0,NULL,0))) { fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql)); perror(""); exit(1); } /* IN NTOP databases,if have some recorders same as currentdate,don't in sert them to data`table*/ getdates(currentdate); charge=1; sprintf(testqbuf,TEST_QUERY,currentdate); if(mysql_query(sock,testqbuf)) { fprintf(stderr,"Query failed (%s)\n",mysql_error(sock)); exit(1); } if (!(res=mysql_store_result(sock))) { fprintf(stderr,"Couldn't get result from %s\n", mysql_error(sock)); exit(1); } i=mysql_num_rows(res); if (i==-1) { printf("couldn't run test select with currentdate\n"); } if ((i!=0)&&(i!=-1)) { charge=0; printf("IN test table,having some recorders included currentdate,error!\n"); exit(1); } mysql_free_result(res); mysql_close(sock); if(!(sock= mysql_real_connect(&mysql,NULL,0,0,"NTOP",0,NULL,0))) { fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql)); perror(""); exit(1); } /#sleep(100)#/ sprintf(selectqbuf,SELECT_QUERY,argv[1],argv[2]); if(mysql_query(sock,selectqbuf)) { fprintf(stderr,"Query failed (%s)\n",mysql_error(sock)); exit(1); } if (!(res=mysql_store_result(sock))) { fprintf(stderr,"Couldn't get result from %s\n", mysql_error(sock)); exit(1); } while ((row=mysql_fetch_row(res))&&charge) { num=atoi(row[1]); sprintf(insertqbuf,INSERT_QUERY,row[0],num,currentdate); mysql_query(sock,insertqbuf);
[1] [2] 下一页
(出处:http://www.sheup.com)
上一页 [1] [2]