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

通讯编程

开发平台:

Visual C++

  1. // Generate statistics from EPA traces 
  2. //   http://ita.ee.lbl.gov/html/contrib/EPA-HTTP.html
  3. //
  4. // All we need to know: 
  5. // 
  6. // (1) client request streams: 
  7. //     <time> <clientID> <serverID> <URL_ID> 
  8. // (2) server page mod stream(s):
  9. //     <serverID> <URL_ID> <PageSize>
  10. //
  11. // Part of the code comes from Steven Gribble's UCB trace parse codes
  12. // 
  13. // $Header: /cvsroot/nsnam/ns-2/indep-utils/webtrace-conv/epa/tr-stat.cc,v 1.3 2005/09/18 23:33:32 tomh Exp $
  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. struct URL {
  25. URL(int i, int sd, int sz) : access(1), id(i), sid(sd), size(sz) {}
  26. int access; // access counts
  27. int id;
  28. int sid, size;
  29. };
  30. struct ReqLog {
  31. ReqLog() {}
  32. ReqLog(double t, unsigned int c, unsigned int s, unsigned int u) :
  33. time(t), cid(c), sid(s), url(u) {}
  34. double time;
  35. unsigned int cid, sid, url;
  36. };
  37. FILE *cf, *sf;
  38. double initTime = -1;
  39. double duration = -1;
  40. double startTime = -1;
  41. Tcl_HashTable cidHash;  // Client id (IP, port) hash
  42. static int client = 0; // client sequence number
  43. static int server = 1;
  44. Tcl_HashTable urlHash; // URL id hash
  45. static int url = 0; // URL sequence number
  46. static int* umap; // URL mapping table, used for url sort
  47. ReqLog* rlog = NULL;
  48. unsigned int num_rlog = 0, sz_rlog = 0;
  49. struct Entry {
  50. char *client;
  51. unsigned int time;
  52. char *url;
  53. int size;
  54. };
  55. static int compare(const void *a1, const void *b1)
  56. {
  57. const ReqLog *a, *b;
  58. a = (const ReqLog*)a1, b = (const ReqLog*)b1;
  59. return (a->time > b->time) ? 1 : 
  60. (a->time == b->time) ? 0 : -1;
  61. }
  62. void sort_rlog()
  63. {
  64. qsort((void *)rlog, num_rlog, sizeof(ReqLog), compare);
  65. double t = rlog[0].time;
  66. for (unsigned int i = 0; i < num_rlog; i++) {
  67. rlog[i].time -= t;
  68. fprintf(cf, "%f %d %d %dn", rlog[i].time, 
  69. rlog[i].cid, rlog[i].sid, umap[rlog[i].url]);
  70. }
  71. // Record trace duration and # of unique urls
  72. fprintf(cf, "i %f %un", rlog[num_rlog-1].time, url);
  73. fprintf(stderr, 
  74. "%d unique clients, %d unique servers, %d unique urls.n", 
  75. client, server, url);
  76. }
  77. static int compare_url(const void* a1, const void* b1)
  78. {
  79. const URL **a, **b;
  80. a = (const URL**)a1, b = (const URL**)b1;
  81. return ((*a)->access > (*b)->access) ? -1:
  82. ((*a)->access == (*b)->access) ? 0 : 1;
  83. }
  84. void sort_url()
  85. {
  86. // XXX use an interval member of Tcl_HashTable
  87. URL** tbl = new URL*[urlHash.numEntries];
  88. Tcl_HashEntry *he;
  89. Tcl_HashSearch hs;
  90. int i = 0, sz = urlHash.numEntries;
  91. for (he = Tcl_FirstHashEntry(&urlHash, &hs);
  92.      he != NULL;
  93.      he = Tcl_NextHashEntry(&hs))
  94. tbl[i++] = (URL*)Tcl_GetHashValue(he);
  95. Tcl_DeleteHashTable(&urlHash);
  96. // sort using access frequencies
  97. qsort((void *)tbl, sz, sizeof(URL*), compare_url);
  98. umap = new int[url];
  99. // write sorted url to page table
  100. for (i = 0; i < sz; i++) {
  101. umap[tbl[i]->id] = i;
  102. fprintf(sf, "%d %d %d %un", tbl[i]->sid, i,
  103. tbl[i]->size, tbl[i]->access);
  104. delete tbl[i];
  105. }
  106. delete []tbl;
  107. }
  108. double lf_analyze(Entry& lfe)
  109. {
  110. double time;
  111. int ne, cid, sid, uid;
  112. Tcl_HashEntry *he;
  113. time = (double)lfe.time;
  114. if (initTime < 0) {
  115. initTime = time;
  116. time = 0;
  117. } else 
  118. time -= initTime;
  119. // If a trace start time is required, don't do anything
  120. if ((startTime > 0) && (time < startTime)) 
  121. return -1;
  122. // If page size is 0, ignore it
  123. if (lfe.size == 0) 
  124. return -1;
  125. // check client id
  126. if (!(he = Tcl_FindHashEntry(&cidHash, (const char *)lfe.client))) {
  127. // new client, allocate a client id
  128. he = Tcl_CreateHashEntry(&cidHash, (const char *)lfe.client, &ne);
  129. client++;
  130. long clientValue = client;
  131. Tcl_SetHashValue(he, clientValue);
  132. cid = client;
  133. } else {
  134. // existing entry, find its client seqno
  135. cid = (long)Tcl_GetHashValue(he);
  136. }
  137. // only a single server for EPA trace
  138. sid = 0;
  139. // check url id
  140. if (!(he = Tcl_FindHashEntry(&urlHash, (const char*)lfe.url))) {
  141. // new client, allocate a client id
  142. he = Tcl_CreateHashEntry(&urlHash, (const char*)lfe.url, &ne);
  143. URL* u = new URL(++url, sid, lfe.size);
  144. Tcl_SetHashValue(he, (const char*)u);
  145. uid = u->id;
  146. } else {
  147. // existing entry, find its client seqno
  148. URL* u = (URL*)Tcl_GetHashValue(he);
  149. u->access++;
  150. uid = u->id;
  151. }
  152. rlog[num_rlog++] = ReqLog(time, cid, sid, uid);
  153. //fprintf(cf, "%f %d %d %dn", time, cid, sid, uid);
  154. if (startTime > 0) 
  155. return time - startTime;
  156. else 
  157. return time;
  158. }
  159. int get_next_entry(Entry& lfe) 
  160. {
  161. char buf[1024];
  162. if (feof(stdin)) 
  163. return 0;
  164. fgets(buf, 1024, stdin);
  165. if (feof(stdin) || ferror(stdin))
  166. return 0;
  167. char *tmp = buf, *code, *method, *date;
  168. lfe.client = strtok(tmp, " ");
  169. date = strtok(NULL, " "); 
  170. method = strtok(NULL, " ");  // GET/POST
  171. *(method++) = 0;
  172. if (strcmp(method, "GET") != 0) 
  173. // Only take GET requests
  174. return -1;
  175. lfe.url = strtok(NULL, " "); 
  176. if (strchr(lfe.url, '?') != NULL) 
  177. // Do not take any url that contains '?'
  178. return -1;
  179. strtok(NULL, " ");  // HTTP/1.0
  180. code = strtok(NULL, " ");  // return code
  181. if ((atoi(code) != 200) && (atoi(code) != 304)) 
  182. return -1;
  183. // last element: size
  184. tmp = strtok(NULL, " ");
  185. lfe.size = atoi(tmp);
  186. // parse date
  187. // date is from internal string of strtok(), we have to copy it. 
  188. // What a stupid strtok()!!!!
  189. tmp = new char[strlen(date)+1];
  190. strcpy(tmp, date);
  191. date = tmp + 1;
  192. lfe.time = 0;
  193. date = strtok(date, ":"); // day
  194. lfe.time = atoi(date);
  195. date = strtok(NULL, ":"); // hour
  196. lfe.time = lfe.time*24 + atoi(date);
  197. date = strtok(NULL, ":"); // minute
  198. lfe.time = lfe.time*60 + atoi(date);
  199. date = strtok(NULL, "]");
  200. lfe.time = lfe.time*60 + atoi(date);
  201. delete []tmp;
  202. return 1;
  203. }
  204. int main(int argc, char**argv)
  205. {
  206. Entry lfntree;
  207. int      ret;
  208. double   ctime;
  209. // Init tcl
  210. Tcl_Interp *interp = Tcl_CreateInterp();
  211. if (Tcl_Init(interp) == TCL_ERROR) {
  212. printf("%sn", interp->result);
  213. abort();
  214. }
  215. Tcl_InitHashTable(&cidHash, TCL_STRING_KEYS);
  216. Tcl_InitHashTable(&urlHash, TCL_STRING_KEYS);
  217. if ((cf = fopen("reqlog", "w")) == NULL) {
  218. printf("cannot open request log.n");
  219. exit(1);
  220. }
  221. if ((sf = fopen("pglog", "w")) == NULL) {
  222. printf("cannot open page log.n");
  223. exit(1);
  224. }
  225. if ((argc > 4) || (argc < 2)) {
  226. printf("Usage: %s <trace size> [<time duration>] [<start_time>]n", argv[0]);
  227. return 1;
  228. }
  229. if (argc >= 3) {
  230. duration = strtod(argv[2], NULL);
  231. if (argc == 4) {
  232. startTime = strtod(argv[3], NULL);
  233. printf("start time = %fn", startTime);
  234. }
  235. }
  236. sz_rlog = strtoul(argv[1], NULL, 10);
  237. rlog = new ReqLog[sz_rlog];
  238. while((ret = get_next_entry(lfntree)) != 0) {
  239. // Analyse one log entry
  240. if (ret < 0)
  241. continue;
  242. ctime = lf_analyze(lfntree);
  243. if ((duration > 0) && (ctime > duration))
  244. break;
  245. }
  246. Tcl_DeleteHashTable(&cidHash);
  247. fprintf(stderr, "sort urln");
  248. sort_url();
  249. fclose(sf);
  250. fprintf(stderr, "sort requestsn");
  251. sort_rlog();
  252. fclose(cf);
  253. fprintf(stderr, 
  254. "%d unique clients, %d unique servers, %d unique urls.n", 
  255. client, server, url);
  256. return 0;
  257. }