|
源代码网推荐 作者:李宇
流量统计
流量统计使用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)
源代码网整理以下CREATETABLEIPtraffic ( IPaddressCHAR(16)NOTNULL, TCPsentRemotelyINT, TCPrcvdFromRemoteINT, UDPsentRemotelyINT, UDPrcvdFromRemoteINT, PRIMARYKEY(IPaddress) ); CREATETABLENameMapper ( IPaddressCHAR(16)NOTNULL, NameCHAR(50), PRIMARYKEY(IPaddress) );
创建备份数据库表test
FieldTypeNullKeyDefaultExtra IPaddressvarchar(20)YESNULL dataint(11)YESNULL datesdateYESNULL
修改ntop源代码中的sql.c
例如:
if(snprintf(sqlBuf,SQL_BUF_LEN,"UPDATEIPtrafficSET" "TCPSentRemotely=%llu," "TCPrcvdFromRemote=%llu," "UDPSentRemotely=%llu," "UDPrcvdFromRemote=%llu" "WHEREIPaddress="%s"", (el->tcpSentRemotely), (el->tcpReceivedFromRemote), (el->udpSentRemotely), (el->udpReceivedFromRemote), el->hostNumIpAddress)<0)traceEvent(TRACE_ERROR,"Bufferoverflow!"); sendto(sqlSocket,sqlBuf,strlen(sqlBuf),0,(structsockaddr*)&dest, sizeof(dest));
将需要的字段保留,其它的去除!
编写数据库表数据的备份程序select_test.c的编译程序(编译时运行make)
源代码网整理以下Makefile: #ThisisaMakefileforselect_test.c CC=gcc INCLUDE=-I/usr/include/mysql LIBPATH=-L/usr/lib/mysql LLIB=-lmysqlclient select_test:select_test.c $(CC)-oselect_testselect_test.c$(INCLUDE)$(LIBPATH)$(LLIB)
数据库表数据备份程序select_test.c:
源代码网整理以下#include #include #include"mysql.h" #include #include #defineSELECT_QUERY "select IPaddress,(UDPrcvdFromRemote+UDPsentRemotely+TCPrcv dFromRemote+TCPsentRemotely)asdatafromIPtrafficwhereIPaddresslike "%s"orIPaddresslike"%s"" #defineINSERT_QUERY"insertintotest(IPaddress,data,dates)values ("%s",%d,"%s")" #defineTEST_QUERY"selectdatesfromtestwheredates="%s"" /*获取当前日期*/ getdates(char*currentdate) { structtimevaldatetemp; structtm*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); } intmain(intargc,char**argv) { unsignedintnum_fields; unsignedinti; intcount,num,charge; MYSQLmysql,*sock; MYSQL_RES*res; MYSQL_FIELD**fields; MYSQL_ROWrow; charselectqbuf[1024]; charinsertqbuf[1024]; chartestqbuf[512]; charcurrentdate[11]; currentdate[10]=0; if(argc!=3) { fprintf(stderr,"usage:select_test
");#设定需要统计的网段 exit(1); } mysql_init(&mysql); if(!(sock=mysql_real_connect(&mysql,NULL,0,0,"NTOP",0,NULL,0))) { fprintf(stderr,"Couldn"tconnecttoengine!
%s
",mysql_error(&mysql)); perror(""); exit(1); } /*INNTOPdatabases,ifhavesomerecorderssameascurrentdate,don"tin sertthemtodata`table*/ getdates(currentdate); charge=1; sprintf(testqbuf,TEST_QUERY,currentdate); if(mysql_query(sock,testqbuf)) { fprintf(stderr,"Queryfailed(%s)
",mysql_error(sock)); exit(1); } if(!(res=mysql_store_result(sock))) { fprintf(stderr,"Couldn"tgetresultfrom%s
", mysql_error(sock)); exit(1); } i=mysql_num_rows(res); if(i==-1) { printf("couldn"truntestselectwithcurrentdate
"); } if((i!=0)&&(i!=-1)) { charge=0; printf("INtesttable,having somerecordersincludedcurrentdate,error!
"); 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"tconnectto engine!
%s
",mysql_error(&mysql)); perror(""); exit(1); } /#sleep(100)#/ sprintf(selectqbuf,SELECT_QUERY,argv[1],argv[2]); if(mysql_query(sock,selectqbuf)) { fprintf(stderr,"Queryfailed(%s)
",mysql_error(sock)); exit(1); } if(!(res=mysql_store_result(sock))) { fprintf(stderr,"Couldn"tgetresultfrom%s
", 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);
源代码网供稿. |