logger.c
上传用户:ladybrid91
上传日期:2007-01-04
资源大小:287k
文件大小:9k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** logger.c
  3. **
  4. ** Copyright (c) 1995 Peter Eriksson <pen@signum.se>
  5. **
  6. ** This program is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** This program is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdio.h>
  20. #include <synch.h>
  21. #include <fcntl.h>
  22. #include <ndbm.h>
  23. #include <string.h>
  24. #include "phttpd.h"
  25. static char *log_path = NULL;
  26. static mutex_t log_lock;
  27. static mutex_t count_lock;
  28. static char *count_path = NULL;
  29. static DBM *count_fd = NULL;
  30.   
  31. static struct count_t totals;
  32. void log_init(char *path, char *cnt_path)
  33. {
  34.     mutex_init(&log_lock, USYNC_THREAD, NULL);
  35.     mutex_init(&count_lock, USYNC_THREAD, NULL);
  36.     
  37.     if (path)
  38.     {
  39. log_path = path;
  40. log_fd = fd_open(path, O_WRONLY+O_CREAT+O_APPEND, 0644);
  41. totals.totalhits = 0;
  42. totals.totalbytes = 0;
  43. totals.starttime = totals.lastaccess = time(NULL);
  44. totals.reserved = 0;
  45.     }
  46.     
  47.     if (cnt_path)
  48.     {
  49. count_path = cnt_path;
  50. count_fd = dbm_open(cnt_path, O_RDWR|O_CREAT, 0644);
  51. if (count_fd != NULL)
  52. {
  53.     datum cnt_datum;
  54.     datum key_datum;
  55.     
  56.     key_datum.dptr = "Totals";
  57.     key_datum.dsize = strlen(key_datum.dptr);
  58.     cnt_datum = dbm_fetch(count_fd, key_datum);
  59.     
  60.     if (cnt_datum.dptr)
  61.     {
  62. memcpy(&totals, cnt_datum.dptr, sizeof(struct count_t));
  63.     }
  64. }
  65.     }
  66. }
  67. void log_reopen(void)
  68. {
  69.     mutex_lock(&log_lock);
  70.     if (log_fd >= 0)
  71. fd_close(log_fd);
  72.     if (log_path != NULL)
  73. log_fd = fd_open(log_path, O_WRONLY+O_CREAT+O_APPEND, 0644);
  74.     mutex_unlock(&log_lock);
  75.     mutex_lock(&count_lock);
  76.     if (count_fd != NULL)
  77. dbm_close(count_fd);
  78.     
  79.     if (count_path != NULL)
  80. count_fd = dbm_open(count_path, O_RDWR|O_CREAT, 0644);
  81.     
  82.     mutex_unlock(&count_lock);
  83. }
  84. void log_close(void)
  85. {
  86.  
  87.     mutex_lock(&log_lock);
  88.     if (log_fd >= 0)
  89.         fd_close(log_fd);
  90.  
  91.     mutex_lock(&count_lock);
  92.     if (count_fd != NULL)
  93.         dbm_close(count_fd);
  94.    
  95.     mutex_unlock(&log_lock);
  96.     mutex_unlock(&count_lock);
  97. }
  98. static const char *const month[] =
  99. {
  100.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  101.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  102. };
  103. char *log_time_r(const time_t *btp, char *buf, int bufsize)
  104. {
  105.     struct tm l_tpb, g_tpb;
  106.     int d, tz_h, tz_m;
  107.     char *s;
  108.     
  109.     if (bufsize < 28)
  110. return NULL;
  111.     
  112.     if (localtime_r(btp, &l_tpb) == NULL)
  113. return NULL;
  114.     
  115.     if (gmtime_r(btp, &g_tpb) == NULL)
  116. return NULL;
  117.     d = (l_tpb.tm_hour * 60 + l_tpb.tm_min) -
  118. (g_tpb.tm_hour * 60 + g_tpb.tm_min);
  119.     
  120.     if (d <= -12*60)
  121.         d = 24*60 + d;
  122.     else if (d >= 24*60)
  123. d = d - 24*60;
  124.     
  125.     if (d < 0)
  126.     {
  127. s = "-";
  128. d = -d;
  129.     }
  130.     else if (d > 0)
  131. s = "+";
  132.     else
  133. s = "";
  134.     
  135.     tz_h = d / 60;
  136.     tz_m = d - (tz_h * 60);
  137.     s_sprintf(buf, bufsize, "%02d/%s/%d:%02d:%02d:%02d %s%02d%02d",
  138.     l_tpb.tm_mday,
  139.     month[l_tpb.tm_mon],
  140.     l_tpb.tm_year + 1900,
  141.     l_tpb.tm_hour,
  142.     l_tpb.tm_min,
  143.     l_tpb.tm_sec,
  144.     s,
  145.     tz_h,
  146.     tz_m);
  147.     return buf;
  148. }
  149.     
  150. void log_connection(struct connectioninfo *cip,
  151.     int result)
  152. {
  153.     struct httpinfo *hip = cip->hip;
  154.     struct mimeinfo *mip = hip ? hip->mip : NULL;
  155.     
  156.     mutex_lock(&log_lock);
  157.     if (log_fd >= 0)
  158.     {
  159. char buf[256], buf1[2048], buf2[2048], buf3[2048], buf4[2048];
  160. char buf5[2048], buf6[2048];
  161. char *url, *request, *hostname, *address;
  162. char *referer = NULL, *client = NULL;
  163. char *auth_user = NULL;
  164. char *ident_user = NULL;
  165. int  headerbytes =0;
  166. url = hip->orig_url;
  167. if (url)
  168.     url = url_quote(hip->url, buf1, sizeof(buf1), "?", 0);
  169. request = hip->request;
  170. if (request)
  171.     request = url_quote(request, buf2, sizeof(buf2), """, 1);
  172. if (mip)
  173. {
  174.     referer = mime_getheader(mip, "REFERER", 1);
  175.     client  = mime_getheader(mip, "USER-AGENT", 1);
  176.     headerbytes = mip->headerbytes;
  177. }
  178. if (referer)
  179.     referer = url_quote(referer, buf3, sizeof(buf3), "", 0);
  180. if (client)
  181.     client = url_quote(client, buf4, sizeof(buf4), """, 1);
  182. if (hip->aip)
  183. {
  184.     auth_user = hip->aip->validated_username;
  185. }
  186. if (auth_user)
  187.     auth_user = url_quote(auth_user, buf5, sizeof(buf5), "", 0);
  188. ident_user = NULL;
  189. (void) ident_get(cip->ident, NULL, NULL, &ident_user);
  190. if (ident_user)
  191.     ident_user = url_quote(ident_user, buf6, sizeof(buf6), "", 0);
  192. hostname = NULL;
  193. address = NULL;
  194. dns_get(cip->client, NULL, &hostname, &address, NULL);
  195. fd_printf(log_fd,
  196.   "%s %s %s [%s] "%s%s%s%s%s%s%s" %d ",
  197.   hostname ? hostname : address,
  198.   ident_user ? ident_user : "-",
  199.   auth_user ? auth_user : "-",
  200.   log_time_r(&cip->cn_time, buf, sizeof(buf)),
  201.   hip->method ? hip->method : "",
  202.   url ? " " : "",
  203.   url ? url : "",
  204.   request ? "?" : "",
  205.   request ? request : "",
  206.   hip->version ? " " : "",
  207.   hip->version ? hip->version : "",
  208.   result);
  209. if (hip->length)
  210.     if (logheadervolume)
  211.      fd_printf(log_fd, "%d", headerbytes+hip->length);
  212.     else
  213.      fd_printf(log_fd, "%d", hip->length);
  214. else
  215.     fd_putc('-', log_fd);
  216. if (extended_logging)
  217. {
  218.     fd_printf(log_fd, " %s %s%s%s",
  219.       referer ? referer : "-",
  220.       client ? """ : "",
  221.       client ? client : "-",
  222.       client ? """ : "");
  223. }
  224. fd_putc('n', log_fd);
  225. fd_flush(log_fd);
  226.     }
  227.     
  228.     mutex_unlock(&log_lock);
  229.     mutex_lock(&count_lock);
  230.     
  231.     if ( result > 0 && result < 400 && count_fd != NULL && hip->orig_url)
  232.     {
  233. struct count_t count;
  234. datum cnt_datum;
  235. datum url_datum;
  236. totals.totalhits++;
  237. totals.totalbytes += (unsigned long)(hip->length);
  238. totals.lastaccess = cip->cn_time;
  239. url_datum.dptr = "Totals";
  240. url_datum.dsize = strlen(url_datum.dptr);
  241. cnt_datum.dptr = (char*)&totals;
  242. cnt_datum.dsize = sizeof(struct count_t);
  243. dbm_store(count_fd, url_datum, cnt_datum, DBM_REPLACE);
  244. if (debug > 2)
  245.     fprintf(stderr, "logger: counter: url=%sn", hip->orig_url);
  246. url_datum.dptr = hip->orig_url;
  247. url_datum.dsize = strlen(url_datum.dptr);
  248. cnt_datum = dbm_fetch(count_fd, url_datum);
  249. if (cnt_datum.dptr)
  250. {
  251.     memcpy(&count, cnt_datum.dptr, sizeof(struct count_t));
  252.     count.totalhits++;
  253.     count.totalbytes += (unsigned long)(hip->length);
  254.     count.lastaccess = cip->cn_time;
  255.     cnt_datum.dptr = (char*)&count;
  256.     cnt_datum.dsize = sizeof(struct count_t);
  257.     dbm_store(count_fd, url_datum, cnt_datum, DBM_REPLACE);
  258. }
  259. else
  260. {
  261.     count.totalhits  = 1;
  262.     count.totalbytes = hip->length;
  263.     count.starttime =
  264. count.lastaccess = cip->cn_time;
  265.     count.reserved  = 0;
  266.     cnt_datum.dptr = (char*)&count;
  267.     cnt_datum.dsize = sizeof(struct count_t);
  268.     dbm_store(count_fd, url_datum, cnt_datum, DBM_INSERT);
  269. };
  270.     }
  271.     
  272.     mutex_unlock(&count_lock);
  273. }
  274. void get_count(char *url, struct count_t *count)
  275. {
  276.     count->totalhits = count->totalbytes = 0;
  277.     if (debug > 2)
  278. fprintf(stderr, "get_count(), url=%sn", url);
  279.     
  280.     mutex_lock(&count_lock);
  281.     
  282.     if (count_fd != NULL && url)
  283.     {
  284. datum cnt_datum;
  285. datum url_datum;
  286. url_datum.dptr = url;
  287. url_datum.dsize = strlen(url);
  288. cnt_datum = dbm_fetch(count_fd, url_datum);
  289. if (cnt_datum.dptr)
  290.     memcpy(count, cnt_datum.dptr, sizeof(struct count_t));
  291. else
  292.     dbm_clearerr(count_fd);
  293.     }
  294.     
  295.     mutex_unlock(&count_lock);
  296. }
  297. void get_totals(struct count_t *count)
  298. {
  299.     count->totalhits  = totals.totalhits;
  300.     count->totalbytes = totals.totalbytes;
  301.     count->starttime  = totals.starttime;
  302.     count->lastaccess  = totals.lastaccess;
  303.     count->reserved = totals.reserved;
  304. }
  305. void print_totals(int fd)
  306. {
  307.     double days = (double)(totals.lastaccess - totals.starttime) /
  308. (24.0*60.0*60.0);
  309.     fd_printf(fd, "<PRE>nFiles Transmitted During Summary Period %14lun",
  310.       totals.totalhits);
  311.     fd_printf(fd, "Bytes Transmitted During Summary Period %14lun",
  312.       totals.totalbytes);
  313.     fd_printf(fd, "Average Files Transmitted Daily         %14.0fn",
  314.       totals.totalhits/days);
  315.     fd_printf(fd, "Average Bytes Transmitted Daily         %14.0fn</PRE>n",
  316.       totals.totalbytes/days);
  317. }
  318. void print_counts(int fd)
  319. {
  320.     if (count_fd != NULL)
  321.     {
  322. struct count_t count;
  323. datum url_datum, cnt_datum;
  324. double thits = totals.totalhits;
  325. double tbytes = totals.totalbytes;
  326.  
  327. fd_puts("<PRE>n", fd);
  328. fd_puts("%Reqs  %Byte  Bytes Sent   Requests  Archive Sectionn", fd);
  329. fd_puts("------ ------ ------------ -------- |------------------------------------n", fd);
  330.  
  331. mutex_lock(&count_lock);
  332. for (url_datum = dbm_firstkey(count_fd);
  333.      url_datum.dptr != NULL;
  334.      url_datum = dbm_nextkey(count_fd))
  335. {
  336.     if (strncmp(url_datum.dptr, "Totals", 6) == 0) continue;
  337.  
  338.     cnt_datum = dbm_fetch(count_fd, url_datum);
  339.     if (cnt_datum.dptr)
  340.     {
  341. memcpy(&count, cnt_datum.dptr, sizeof(struct count_t));
  342. fd_printf(fd, "%6.2f %6.2f %12d %8d | %.*sn",
  343.   100.0*(double)(count.totalhits)/thits,
  344.   100.0*(double)(count.totalbytes)/tbytes,
  345.   count.totalbytes, count.totalhits,
  346.   url_datum.dsize, url_datum.dptr);
  347.     }
  348.     else
  349. break;
  350.            
  351. }
  352.  
  353. mutex_unlock(&count_lock);
  354.  
  355. fd_puts("</PRE>n", fd);
  356.     }
  357. }    
  358.