tr-stat.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Generate statistics from UCB traces
  3.  * All we need to know: 
  4.  * 
  5.  * (1) client request streams: 
  6.  *     <time> <clientID> <serverID> <URL_ID> 
  7.  * (2) server page mod stream(s):
  8.  *     <serverID> <URL_ID> <PageSize> <access times>
  9.  *
  10.  * Part of the code comes from Steven Gribble's UCB trace parse code.
  11.  * 
  12.  * $Header: /cvsroot/nsnam/ns-2/indep-utils/webtrace-conv/ucb/tr-stat.cc,v 1.4 2005/09/18 23:33:33 tomh Exp $
  13.  */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <time.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <arpa/inet.h>
  23. #include <tcl.h>
  24. #include "logparse.h"
  25. Tcl_HashTable cidHash;  /* Client id (IP, port) hash */
  26. int client = 0; /* client sequence number */
  27. Tcl_HashTable sidHash; /* server id (IP, port) hash */
  28. int server = 0; /* server sequence number */
  29. Tcl_HashTable urlHash; /* URL id hash */
  30. int url = 0; /* URL sequence number */
  31. int* umap; /* URL mapping table, used for url sort */
  32. struct URL {
  33. URL(int i, int sd, int sz) : access(1), id(i), sid(sd), size(sz) {}
  34. int access; /* access counts */
  35. int id;
  36. int sid, size;
  37. };
  38. FILE *cf, *sf;
  39. double initTime = -1;
  40. double duration = -1;
  41. double startTime = -1;
  42. struct ReqLog {
  43. ReqLog() {}
  44. ReqLog(double t, unsigned int c, unsigned int s, unsigned int u) :
  45. time(t), cid(c), sid(s), url(u) {}
  46. double time;
  47. unsigned int cid, sid, url;
  48. };
  49. ReqLog* rlog = NULL;
  50. unsigned int num_rlog = 0, sz_rlog = 0;
  51. int compare(const void *a1, const void *b1)
  52. {
  53. const ReqLog *a, *b;
  54. a = (const ReqLog*)a1, b = (const ReqLog*)b1;
  55. return (a->time > b->time) ? 1 : 
  56. (a->time == b->time) ? 0 : -1;
  57. }
  58. void sort_rlog()
  59. {
  60. qsort((void *)rlog, num_rlog, sizeof(ReqLog), compare);
  61. double t = rlog[0].time;
  62. for (unsigned int i = 0; i < num_rlog; i++) {
  63. rlog[i].time -= t;
  64. fprintf(cf, "%f %d %d %dn", rlog[i].time, 
  65. rlog[i].cid, rlog[i].sid, umap[rlog[i].url]);
  66. }
  67. delete []umap;
  68. /* Record trace duration and # of unique urls */
  69. fprintf(cf, "i %f %un", rlog[num_rlog-1].time, url);
  70. }
  71. int compare_url(const void* a1, const void* b1)
  72. {
  73. const URL **a, **b;
  74. a = (const URL**)a1, b = (const URL**)b1;
  75. return ((*a)->access > (*b)->access) ? -1:
  76. ((*a)->access == (*b)->access) ? 0 : 1;
  77. }
  78. void sort_url()
  79. {
  80. /* XXX use an interval member of Tcl_HashTable */
  81. URL** tbl = new URL*[urlHash.numEntries];
  82. Tcl_HashEntry *he;
  83. Tcl_HashSearch hs;
  84. int i = 0, sz = urlHash.numEntries;
  85. for (he = Tcl_FirstHashEntry(&urlHash, &hs);
  86.      he != NULL;
  87.      he = Tcl_NextHashEntry(&hs))
  88. tbl[i++] = (URL*)Tcl_GetHashValue(he);
  89. Tcl_DeleteHashTable(&urlHash);
  90. /* sort using access frequencies */
  91. qsort((void *)tbl, sz, sizeof(URL*), compare_url);
  92. umap = new int[url];
  93. /* write sorted url to page table */
  94. for (i = 0; i < sz; i++) {
  95. umap[tbl[i]->id] = i;
  96. fprintf(sf, "%d %d %d %un", tbl[i]->sid, i,
  97. tbl[i]->size, tbl[i]->access);
  98. delete tbl[i];
  99. }
  100. delete []tbl;
  101. }
  102. const unsigned long MAX_FILESIZE = 10000000;
  103. double lf_analyze(lf_entry& lfe)
  104. {
  105. double time;
  106. int id[2], ne, cid, sid, uid;
  107. Tcl_HashEntry *he;
  108. /* Because client/server pragma bits are in network order, we 
  109.  * do the filtering here
  110.  *  
  111.  * We do not count in entries with "no-cache" flag
  112.  */
  113. if ((lfe.cprg != 0xff) && (lfe.cprg & PB_CLNT_NO_CACHE))
  114. return -1;
  115. if ((lfe.sprg != 0xff) && (lfe.sprg & PB_SRVR_NO_CACHE))
  116. return -1;
  117. /* Convert to host order for size comparison, etc. */
  118. lf_convert_order(&lfe);
  119. /* We don't consider pages with size 0 */
  120. if (lfe.rhl + lfe.rdl == 0)
  121. return -1;
  122. /* We don't consider file size larger than 10MB */
  123. if (lfe.rhl + lfe.rdl > MAX_FILESIZE)
  124. return -1;
  125. /* Analyze URL. *MUST* be done before anything else because this
  126.  * filters out entries
  127.  */
  128. char *str, *idx = (char *)lfe.url, *tmp;
  129. tmp = strtok(idx, " ");
  130. if (strcmp(tmp, "GET") != 0) { 
  131. /* We only count GETs */
  132. return -1;
  133. }
  134. str = strtok(NULL, "."); /* This is the URL to be entered */
  135. time = (double)lfe.crs + (double)lfe.cru/(double)1000000.0;
  136. if (initTime < 0) {
  137. initTime = time;
  138. time = 0;
  139. } else 
  140. time -= initTime;
  141. /* If a trace start time is required, don't do anything */
  142. if ((startTime > 0) && (time < startTime)) 
  143. return -1;
  144. /* check client id */
  145. if (!(he = Tcl_FindHashEntry(&cidHash, (const char *)lfe.cip))) {
  146. /* new client, allocate a client id */
  147. he = Tcl_CreateHashEntry(&cidHash, (const char *)lfe.cip, &ne);
  148. client++;
  149. long clientValue = client;
  150. Tcl_SetHashValue(he, clientValue);
  151. cid = client;
  152. } else {
  153. /* existing entry, find its client seqno */
  154. cid = (long)Tcl_GetHashValue(he);
  155. }
  156. /* check server id */
  157. id[0] = lfe.sip;
  158. id[1] = lfe.spt;
  159. if (!(he = Tcl_FindHashEntry(&sidHash, (const char *)id))) {
  160. /* new client, allocate a client id */
  161. he = Tcl_CreateHashEntry(&sidHash, (const char *)id, &ne);
  162. server++;
  163. long serverValue = server;
  164. Tcl_SetHashValue(he, serverValue);
  165. sid = server;
  166. } else {
  167. /* existing entry, find its client seqno */
  168. sid = (long)Tcl_GetHashValue(he);
  169. }
  170. /* check url id */
  171. if (!(he = Tcl_FindHashEntry(&urlHash, str))) {
  172. /* new client, allocate a client id */
  173. he = Tcl_CreateHashEntry(&urlHash, str, &ne);
  174. URL* u = new URL(++url, sid, lfe.rhl+lfe.rdl);
  175. Tcl_SetHashValue(he, (const char*)u);
  176. uid = u->id;
  177. /* fprintf(sf, "%d %d %ldn", sid, u->id, lfe.rhl+lfe.rdl); */
  178. } else {
  179. /* existing entry, find its client seqno */
  180. URL* u = (URL*)Tcl_GetHashValue(he);
  181. u->access++;
  182. uid = u->id;
  183. }
  184. rlog[num_rlog++] = ReqLog(time, cid, sid, uid);
  185. /*fprintf(cf, "%f %d %d %dn", time, cid, sid, uid); */
  186. if (startTime > 0) 
  187. return time - startTime;
  188. else 
  189. return time;
  190. }
  191. int main(int argc, char**argv)
  192. {
  193. lf_entry lfntree;
  194. int      ret;
  195. double   ctime;
  196. /* Init tcl */
  197. Tcl_Interp *interp = Tcl_CreateInterp();
  198. if (Tcl_Init(interp) == TCL_ERROR) {
  199. printf("%sn", interp->result);
  200. abort();
  201. }
  202. Tcl_InitHashTable(&cidHash, TCL_ONE_WORD_KEYS);
  203. Tcl_InitHashTable(&sidHash, 2);
  204. Tcl_InitHashTable(&urlHash, TCL_STRING_KEYS);
  205. if ((cf = fopen("reqlog", "w")) == NULL) {
  206. printf("cannot open request log.n");
  207. exit(1);
  208. }
  209. if ((sf = fopen("pglog", "w")) == NULL) {
  210. printf("cannot open page log.n");
  211. exit(1);
  212. }
  213. if ((argc < 2) || (argc > 4)) {
  214. printf("Usage: %s <trace size> [<time duration>] [<start_time>]n", argv[0]);
  215. return 1;
  216. }
  217. if (argc >= 3) {
  218. duration = strtod(argv[2], NULL);
  219. if (argc == 4) {
  220. startTime = strtod(argv[3], NULL);
  221. printf("start time = %fn", startTime);
  222. }
  223. }
  224. sz_rlog = strtoul(argv[1], NULL, 10);
  225. rlog = new ReqLog[sz_rlog];
  226. while(1) {
  227. if ((ret = lf_get_next_entry(0, &lfntree, 0)) != 0) {
  228. if (ret == 1) {
  229. /* EOF */
  230. break;
  231. }
  232. fprintf(stderr, "Failed to get next entry.n");
  233. exit(1);
  234. }
  235. /*  Analyse one log entry */
  236. ctime = lf_analyze(lfntree);
  237. free(lfntree.url);
  238. if ((duration > 0) && (ctime > duration))
  239. break;
  240. }
  241. Tcl_DeleteHashTable(&cidHash);
  242. Tcl_DeleteHashTable(&sidHash);
  243. fprintf(stderr, "sort urln");
  244. sort_url();
  245. fclose(sf);
  246. fprintf(stderr, "sort requestsn");
  247. sort_rlog();
  248. fclose(cf);
  249. fprintf(stderr, 
  250. "%d unique clients, %d unique servers, %d unique urls.n", 
  251. client, server, url);
  252. return 0;
  253. }