I am evaluating nntpcache for use as a front end to our main news server set here. As part of this I have been hacking the code a bit, and decided it was a reasonable stage to contribute my changes back. There are 2 patches attached to this mail. Both are relative to 1.0.6.5, they apply in sequence (I doubt that 2 will work without 1, However, the changes in 2 are slightly more specific to what I want than generally applicable). nntpcache-1.0.6.5-planet1.patch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - hack to allow stats to be obtained by getting a magic article ID so "article <statistics@nntpcache>" will get the current stats - Complete removal of the ftell method of client byte counts (it not only failed under linux, it repositioned the read stream which broke clients that streamed commands - like Emacs/Gnus) - now does byte counts the hard way - in emit*(). This will cost some CPU - slight mod to remove %m from syslog messages which had no sys error. - minor setproctitle changes to make work under linux - fixes for SIGHUP brokenness (managed to listen to no ports at all after SIGHUP). - stats stuff is now emit-ed rather than fprint-ed nntpcache-1.0.6.5-planet1.patch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - parameterised Exit(), all calls previously existing now changed to Exit(1) - Normal (end of client) exit also calls Exit() (but with parameter 0) - Stats handling of articles (missed the way that they are specially written previously). - Adding of nnrpd like log messages to allow the same scripts to process them. - Adding of per group article count for above. - Adding of CPU time totalling for log messages, also put into stats structure and report. The CPU time usage uses times() only. It could be rehashed like the code in nnrpd to be more portable, but currently its hard coded. I don't think I have broken any other portability stuff... Hope this is useful. So far it looks good on our testbed. I am going to now run some serious tests on it and if those are as positive as I expect I am going to license and run it all over our site. Nigel.
Index: nntpcache/article.c diff -u nntpcache/article.c:1.1.1.1 nntpcache/article.c:1.2 --- nntpcache/article.c:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/article.c Wed Jul 9 13:51:15 1997 @@ -3,6 +3,8 @@ #include "nntpcache.h" #include "mmap.h" +#define STATS_MSGID "statistics@nntpcache" + X (void rfc822lower (char *s)) { for (; *s != '@'; s++) @@ -381,6 +383,31 @@ return TRUE; } + +/* This routine just shoves out a dummy art with the stats in it */ + +static bool dummyStatsArticle(struct command *cmd) +{ + enum cmds type=cmd->val; + +/* if (!PutStats(Stats)) + * loge (("couldn't put statistics via IPC")); + */ + emit_follows(type, 0, STATS_MSGID, 1); + if (type==c_head || type == c_article) { + emit("Newsgroups: nntpcache.statistics\r\n"); + emitf("Message-ID: <%s>\r\n", STATS_MSGID); + emitf("Date: %s\r\n", NewsDate(time(NULL))); + emit("Subject: NNTPCACHE Statistics\r\n"); + emit("From: NNTPCACHE Statistics <nntpcache>\r\n"); + } + if (type==c_body || type == c_article) { + PrintStats(); + } + emit(".\r\n"); + return TRUE; +} + /* * handle article, head, body and stat commands * this routine is insane. most of the insanity is @@ -481,6 +508,8 @@ Stats->msgid_cache++; } } + else if (!strcmp(msgid, STATS_MSGID)) + return(dummyStatsArticle(cmd)); } else /* ahh, the simple alternative (!getbyid) */ { if (type == c_head || type == c_stat) Index: nntpcache/ipc.c diff -u nntpcache/ipc.c:1.1.1.1 nntpcache/ipc.c:1.2 --- nntpcache/ipc.c:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/ipc.c Wed Jul 9 13:51:15 1997 @@ -103,22 +103,11 @@ return TRUE; } -X (void updateFtell ()) -{ - int t; - t = ftell (clientin); - if (t > 0) - Stats->client_read_bytes = t; - t = ftell (clientout); - if (t > 0) - Stats->client_write_bytes = t; -} X (bool PutStats (struct stats *s)) { s->type = IPC_STATS; s->client_elapsed = time (NULL) - s->time_client_started; - updateFtell (); if (write (Daddy, (char *) s, sizeof *s) != sizeof *s) return FALSE; return TRUE; Index: nntpcache/log.h diff -u nntpcache/log.h:1.1.1.1 nntpcache/log.h:1.2 --- nntpcache/log.h:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/log.h Wed Jul 9 13:51:15 1997 @@ -35,7 +35,7 @@ {\ char _buf[4096]; /* security - don't let this overflow */ \ logPrintP = _buf; \ - syslog(LOG_ERR, "%s:%d:%m: %s", __FILE__, __LINE__, logPrint x);\ + syslog(LOG_ERR, (errno ? "%s:%d:%m: %s" : "%s:%d: %s"), __FILE__, __LINE__, logPrint x);\ }\ } while(0) @@ -46,7 +46,7 @@ {\ char _buf[4096]; /* security - don't let this overflow */ \ logPrintP = _buf; \ - syslog(LOG_WARNING, "%s:%d:%m: %s", __FILE__, __LINE__, logPrint x);\ + syslog(LOG_WARNING, (errno ? "%s:%d:%m: %s" : "%s:%d: %s"), __FILE__, __LINE__, logPrint x);\ }\ } while(0) Index: nntpcache/nntpcache.c diff -u nntpcache/nntpcache.c:1.1.1.1 nntpcache/nntpcache.c:1.4 --- nntpcache/nntpcache.c:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/nntpcache.c Wed Jul 9 13:51:16 1997 @@ -85,8 +85,10 @@ { signal (SIGTERM, sigterm); signal (SIGINT, sigterm); - if (!Daemon || InDaemon) + if (!Daemon || InDaemon) { + errno = 0; logw (("caught SIGTERM or SIGINT..syncing database...syncing disks...exiting")); + } Exit (); } @@ -605,6 +607,7 @@ struct hostent *hp; bool f_swap_child = FALSE; struct authent *gauth = NULL; /* stop gcc complaining */ + int daemon_port = -1; /* keep -Wall quiet */ #ifdef MMALLOC /* init_mmalloc(NULL); */ #endif @@ -620,8 +623,6 @@ \n\ -nntpcache development team\n"); - initsetproctitle(argc, argv, envp); - setproctitle("initialising"); while ((c = getopt (argc, argv, "ehinb:rc:s")) != -1) switch (c) { @@ -657,6 +658,8 @@ default: usage (argv[0]); } + initsetproctitle(argc, argv, envp); + setproctitle("initialising"); umask (022); if (!sig_hup && Daemon && !nodetach) { @@ -794,7 +797,6 @@ char *io_buf; #endif struct sockaddr_in *in; - int daemon_port = -1; /* keep -Wall quiet */ int high_fd = -1; /* keep -Wall quiet */ fd_set r_set, rt_set, et_set; FD_ZERO (&r_set); @@ -841,7 +843,11 @@ fclose (fh); } } - else FD_SET (daemon_port, &r_set); + else + { + FD_SET (daemon_port, &r_set); + high_fd = daemon_port; + } open_mmap(); set_rebuild_time(); sig_hup = FALSE; @@ -878,7 +884,7 @@ } if (sig_hup) { - errno = s_errno; + errno = 0; logw (("caught SIGHUP, restarting...")); goto reload; } @@ -901,6 +907,7 @@ } if (sig_hup) { + errno = 0; logw (("caught SIGHUP, restarting...")); goto reload; } @@ -1049,7 +1056,8 @@ Exit (); } if (con.statistics) - updateFtell (); + Stats->client_read_bytes += strlen(buf); + sscanf(buf, "%31[^\r\n\t ]%*[\r\n\t ]%127[^\r\n]", a0, a1); if (!*a0) continue; Index: nntpcache/sockets.c diff -u nntpcache/sockets.c:1.1.1.1 nntpcache/sockets.c:1.2 --- nntpcache/sockets.c:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/sockets.c Wed Jul 9 13:51:16 1997 @@ -405,6 +405,8 @@ X (int emit (char *s)) { logToClient (s); + if (con.statistics) + Stats->client_write_bytes += strlen(s); return fputs (s, clientout)!=EOF; } @@ -412,6 +414,8 @@ { fputs (s, clientout); logToClient (s); + if (con.statistics) + Stats->client_write_bytes += strlen(s) + 2; return fputs ("\r\n", clientout); } @@ -428,6 +432,8 @@ } i=vfprintf(clientout, fmt, ap); va_end(ap); + if (con.statistics) + Stats->client_write_bytes += i; return i; } @@ -448,6 +454,7 @@ } i=vfprintf(scfg->fh, fmt, ap); va_end(ap); + Stats->server_write_bytes += i; return i; } @@ -467,6 +474,7 @@ } i=vfprintf(scfg->fh, fmt, ap); va_end(ap); + Stats->server_write_bytes += i; return i; } @@ -491,6 +499,7 @@ if (!cf) return 0; logToServer (cf->host, s); + Stats->server_write_bytes += strlen(s); return fputs(s, cf->fh)!=EOF; } @@ -498,6 +507,7 @@ { if (Cfemit(cf, s)==0) return 0; + Stats->server_write_bytes += strlen(s) + 2; return Cfemit(cf, "\r\n"); } Index: nntpcache/stats.c diff -u nntpcache/stats.c:1.1.1.1 nntpcache/stats.c:1.2 --- nntpcache/stats.c:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/stats.c Wed Jul 9 13:51:16 1997 @@ -10,68 +10,68 @@ time_t ti=time(NULL); int dif=ti-s->time_statistics_started; /* keep initial \r\n -- used for head/body sep */ - fprintf(clientout, "\r\nNNTPCACHE %s statistics on %s, %s\r\n", VERSION, Host, con.bindAddr); - fprintf(clientout, "\r\nOVERALL:\r\n\r\n"); - fprintf(clientout, "\tStatistics gathering commenced: %24s\r\n", NewsDate(s->time_statistics_started)); - fprintf(clientout, "\tCurrent nntpcached started: %24s\r\n", NewsDate(s->time_server_started)); - fprintf(clientout, "\tServers run during statistical period: %24d\r\n", s->servers_run); - fprintf(clientout, "\tClients active: %24d\r\n", s->clients_active); - fprintf(clientout, "\tClient connects: %24d\r\n", s->client_connects); - fprintf(clientout, "\tOuting server connections: %24d\r\n", s->server_connects); - fprintf(clientout, "\tOuting server connections (failed): %24d\r\n", s->server_connects_failed); - fprintf(clientout, "\tTotal data from remote servers (bytes): %24s\r\n", c(s->server_read_bytes)); - fprintf(clientout, "\tTotal data to remote servers (bytes): %24s\r\n", c(s->server_write_bytes)); - fprintf(clientout, "\tTotal data from clients (bytes): %24s\r\n", c(s->client_read_bytes)); - fprintf(clientout, "\tTotal data to clients (bytes): %24s\r\n", c(s->client_write_bytes)); - fprintf(clientout, "\tTotal cache cache efficiency: %23.2f%%\r\n", 1.0-((float)(s->server_read_bytes+s->server_write_bytes+1)/(float)(s->client_write_bytes+s->client_read_bytes+1))); - fprintf(clientout, "\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes)); - fprintf(clientout, "\tIPC messages to children: %24d\r\n", s->ipc_messages_out); - fprintf(clientout, "\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes)); - fprintf(clientout, "\tIPC messages from children: %24d\r\n", s->ipc_messages_in); - fprintf(clientout, "\tIPC messages from children (bytes): %24s\r\n", c(s->ipc_messages_in_bytes)); - fprintf(clientout, "\tTotal time elapsed in children: %24s\r\n", nnitod(s->client_elapsed)); - fprintf(clientout, "\tDatabase stores: %24d\r\n", s->dbz_stores); - fprintf(clientout, "\tDatabase fetches: %24d\r\n", s->dbz_fetches); - fprintf(clientout, "\tDatabase size: %24s\r\n", c(s->dbz_len)); - fprintf(clientout, "\t\"group\" commands: %24d\r\n", s->group); - fprintf(clientout, "\t\"listgroup\" commands: %24d\r\n", s->listgroup); - fprintf(clientout, "\tGroups cached with > 0 articles: %24d\r\n", s->groups_cached); - fprintf(clientout, "\tGroups expired: %24d\r\n", s->expire_groups); - fprintf(clientout, "\tArticles expired: %24d\r\n", s->expire_articles); - fprintf(clientout, "\tPosts: %24d\r\n", s->posts); - fprintf(clientout, "\tPosts (crossposted): %24d\r\n", s->posts_cross); - fprintf(clientout, "\tPosts (failed): %24d\r\n", s->posts_failed); - fprintf(clientout, "\tPosts (bytes): %24s\r\n", c(s->posts_bytes)); - fprintf(clientout, "\tIncoming crossposts: %24d\r\n", s->crossposts); - fprintf(clientout, "\tIncoming crossposts (bytes): %24s\r\n", c(s->crossposts_bytes)); -fprintf(clientout, "\ + emitf("\r\nNNTPCACHE %s statistics on %s, %s\r\n", VERSION, Host, con.bindAddr); + emitf("\r\nOVERALL:\r\n\r\n"); + emitf("\tStatistics gathering commenced: %24s\r\n", NewsDate(s->time_statistics_started)); + emitf("\tCurrent nntpcached started: %24s\r\n", NewsDate(s->time_server_started)); + emitf("\tServers run during statistical period: %24d\r\n", s->servers_run); + emitf("\tClients active: %24d\r\n", s->clients_active); + emitf("\tClient connects: %24d\r\n", s->client_connects); + emitf("\tOuting server connections: %24d\r\n", s->server_connects); + emitf("\tOuting server connections (failed): %24d\r\n", s->server_connects_failed); + emitf("\tTotal data from remote servers (bytes): %24s\r\n", c(s->server_read_bytes)); + emitf("\tTotal data to remote servers (bytes): %24s\r\n", c(s->server_write_bytes)); + emitf("\tTotal data from clients (bytes): %24s\r\n", c(s->client_read_bytes)); + emitf("\tTotal data to clients (bytes): %24s\r\n", c(s->client_write_bytes)); + emitf("\tTotal cache cache efficiency: %23.2f%%\r\n", 1.0-((float)(s->server_read_bytes+s->server_write_bytes+1)/(float)(s->client_write_bytes+s->client_read_bytes+1))); + emitf("\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes)); + emitf("\tIPC messages to children: %24d\r\n", s->ipc_messages_out); + emitf("\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes)); + emitf("\tIPC messages from children: %24d\r\n", s->ipc_messages_in); + emitf("\tIPC messages from children (bytes): %24s\r\n", c(s->ipc_messages_in_bytes)); + emitf("\tTotal time elapsed in children: %24s\r\n", nnitod(s->client_elapsed)); + emitf("\tDatabase stores: %24d\r\n", s->dbz_stores); + emitf("\tDatabase fetches: %24d\r\n", s->dbz_fetches); + emitf("\tDatabase size: %24s\r\n", c(s->dbz_len)); + emitf("\t\"group\" commands: %24d\r\n", s->group); + emitf("\t\"listgroup\" commands: %24d\r\n", s->listgroup); + emitf("\tGroups cached with > 0 articles: %24d\r\n", s->groups_cached); + emitf("\tGroups expired: %24d\r\n", s->expire_groups); + emitf("\tArticles expired: %24d\r\n", s->expire_articles); + emitf("\tPosts: %24d\r\n", s->posts); + emitf("\tPosts (crossposted): %24d\r\n", s->posts_cross); + emitf("\tPosts (failed): %24d\r\n", s->posts_failed); + emitf("\tPosts (bytes): %24s\r\n", c(s->posts_bytes)); + emitf("\tIncoming crossposts: %24d\r\n", s->crossposts); + emitf("\tIncoming crossposts (bytes): %24s\r\n", c(s->crossposts_bytes)); +emitf("\ \r\n\ LISTS:\r\n\ \r\n\ List-name---- --out-of-cache -----into-cache hits --xfer-per-hour lines -length\r\n"); -fprintf(clientout, "\ +emitf("\ active %7d %7s %7d %7s %3.0f%% %7.2f %7s %5d %7s\r\n", s->list_active_cache, c(s->list_active_cache_bytes), s->list_active_cached, c(s->list_active_cached_bytes), 100.0*(s->list_active_cache_bytes+1)/(float)(s->list_active_cache_bytes+s->list_active_cached_bytes+1), (s->list_active_cache+s->list_active_cached)/(dif/3600.0), c(((s->list_active_cache_bytes+s->list_active_cached_bytes)*3600.0)/dif), s->active_entries, c(s->active_len)); -fprintf(clientout, "\ +emitf("\ active.times %7d %7s %7d %7s %3.0f%% %7.2f %7s %5d %7s\r\n", s->list_active_times_cache, c(s->list_active_times_cache_bytes), s->list_active_times_cached, c(s->list_active_times_cached_bytes), 100*(s->list_active_times_cache_bytes+1)/(float)(s->list_active_times_cache_bytes+s->list_active_times_cached_bytes+1), (s->list_active_times_cache+s->list_active_times_cached)/(dif/3600.0), c((s->list_active_times_cache_bytes+s->list_active_times_cached_bytes)/(dif/3600.0)), s->active_times_entries, c(s->active_times_len)); -fprintf(clientout, "\ +emitf("\ newsgroups %7d %7s %7d %7s %3.0f%% %7.2f %7s %5d %7s\r\n", s->list_newsgroups_cache, c(s->list_newsgroups_cache_bytes), s->list_newsgroups_cached, c(s->list_newsgroups_cached_bytes), 100.0*(s->list_newsgroups_cache_bytes+1)/(float)(s->list_newsgroups_cache_bytes+s->list_newsgroups_cached_bytes+1), (s->list_newsgroups_cache+s->list_newsgroups_cached)/(dif/3600.0), c((s->list_newsgroups_cache_bytes+s->list_newsgroups_cached_bytes)/(dif/3600.0)), s->newsgroups_entries, c(s->newsgroups_len)); -fprintf(clientout, "\ -overview_fmt %7d %7s %7d %7s %3.0f%% %7.2f %7s %5d %7s\r\n", s->list_overview_fmt_cache, c(s->list_overview_fmt_cache_bytes), s->list_overview_fmt_cached, c(s->list_overview_fmt_cached_bytes), 100.0*(s->list_overview_fmt_cache_bytes+1)/(float)(s->list_overview_fmt_cache_bytes+s->list_overview_fmt_cached_bytes+1), (s->list_overview_fmt_cache+s->list_overview_fmt_cached)/(dif/3600.0), c((s->list_overview_fmt_cache_bytes+s->list_overview_fmt_cached_bytes)/(dif/3600.0)), s->overview_fmt_entries, c(s->overview_fmt_len)); -fprintf(clientout, "\r\n\ +emitf("\ +overview_fmt %7d %7s %7d %7s %3.0f%% %7.2f %7s %5d %7s\r\n", s->list_overview_fmt_cache, c(s->list_overview_fmt_cache_bytes), s->list_overview_fmt_cached, c(s->list_overview_fmt_cached_bytes), 100.0*(s->list_overview_fmt_cache_bytes+1)/(float)(s->list_overview_fmt_cache_bytes+s->list_overview_fmt_cached_bytes+1), (s->list_overview_fmt_cache+s->list_overview_fmt_cached)/(dif/3600.0), c((s->list_overview_fmt_cache_bytes+s->list_overview_fmt_cached_bytes)/(dif/3600.0)), s->overview_fmt_entries, c(s->overview_fmt_len)); +emitf("\r\n\ MESSAGES:\r\n\ \r\n\ Data-type---- --out-of-cache -----into-cache hits ----------proxy xfer-per-hour\r\n"); -fprintf(clientout, "\ +emitf("\ article %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->article_cache, c(s->article_cache_bytes), s->article_cached, c(s->article_cached_bytes), 100.0*(s->article_cache_bytes+1)/(float)(s->article_cache_bytes+s->article_cached_bytes+1), s->article_proxy, c(s->article_proxy_bytes), (s->article_cache+s->article_cached)/(dif/3600.0), c(((s->article_cache_bytes+s->article_cached_bytes)*3600.0)/dif)); -fprintf(clientout, "\ +emitf("\ head %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->head_cache, c(s->head_cache_bytes), s->head_cached, c(s->head_cached_bytes), 100.0*(s->head_cache_bytes+1)/(float)(s->head_cache_bytes+s->head_cached_bytes+1), s->head_proxy, c(s->head_proxy_bytes), ((s->head_cache+s->head_cached)*3600.0)/dif, c(((s->head_cache_bytes+s->head_cached_bytes)*3600.0)/dif)); -fprintf(clientout, "\ +emitf("\ body %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->body_cache, c(s->body_cache_bytes), s->body_cached, c(s->body_cached_bytes), 100.0*(s->body_cache_bytes+1)/(float)(s->body_cache_bytes+s->body_cached_bytes+1), s->body_proxy, c(s->body_proxy_bytes), ((s->body_cache+s->body_cached)*3600.0)/dif, c(((s->body_cache_bytes+s->body_cached_bytes)*3600)/dif)); -fprintf(clientout, "\ +emitf("\ xover %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->xover_cache, c(s->xover_cache_bytes), s->xover_cached, c(s->xover_cached_bytes), 100.0*(s->xover_cache_bytes+1)/(float)(s->xover_cache_bytes+s->xover_cached_bytes+1), s->xover_proxy, c(s->xover_proxy_bytes), ((s->xover_cache+s->xover_cached+s->xover_proxy)*3600.0)/dif, c(((s->xover_cache_bytes+s->xover_cached_bytes+s->xover_proxy_bytes)*3600.0)/dif)); -fprintf(clientout, "\ -xhdr %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->xhdr_cache, c(s->xhdr_cache_bytes), s->xhdr_cached, c(s->xhdr_cached_bytes), 100.0*(s->xhdr_cache_bytes+1)/(float)(s->xhdr_cache_bytes+s->xhdr_cached_bytes+1), s->xhdr_proxy, c(s->xhdr_proxy_bytes), ((s->xhdr_cache+s->xhdr_cached+s->xhdr_proxy)*3600.0)/dif, c(((s->xhdr_cache_bytes+s->xhdr_cached_bytes+s->xhdr_proxy_bytes)*3600.0)/dif)); -fprintf(clientout, "\ +emitf("\ +xhdr %7d %7s %7d %7s %3.0f%% %7d %7s %5.0f %7s\r\n", s->xhdr_cache, c(s->xhdr_cache_bytes), s->xhdr_cached, c(s->xhdr_cached_bytes), 100.0*(s->xhdr_cache_bytes+1)/(float)(s->xhdr_cache_bytes+s->xhdr_cached_bytes+1), s->xhdr_proxy, c(s->xhdr_proxy_bytes), ((s->xhdr_cache+s->xhdr_cached+s->xhdr_proxy)*3600.0)/dif, c(((s->xhdr_cache_bytes+s->xhdr_cached_bytes+s->xhdr_proxy_bytes)*3600.0)/dif)); +emitf("\ msgid %7d %7s %7d %7s %3.0f%% %5.0f %7s\r\n", s->msgid_cache, c(s->msgid_cache_bytes), s->msgid_cached, c(s->msgid_cached_bytes), 100.0*(s->msgid_cache_bytes+1)/(float)(s->msgid_cache_bytes+s->msgid_cached_bytes+1), ((s->msgid_cache+s->msgid_cached)*3600.0)/dif, c(((s->msgid_cache_bytes+s->msgid_cached_bytes)*3600.0)/dif)); convFree(); return; @@ -80,6 +80,7 @@ X(bool PrintStats()) { struct stats stats, *s=&stats; + if (!GetStats(s, "")) loge (("couldn't get statistics via IPC")); print_stats(s);
Index: nntpcache/acc.c diff -u nntpcache/acc.c:1.1.1.1 nntpcache/acc.c:1.2 --- nntpcache/acc.c:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/acc.c Thu Jul 10 11:23:08 1997 @@ -175,7 +175,7 @@ if (!p) { loge (("bad filter header/scope %s in file %s: %s", scope, fi, buf)); - Exit(); + Exit(1); } *p='\0'; f->scope = sc_header; @@ -188,7 +188,7 @@ if (sscanf(weight, "%d", &f->weight)!=1) { loge (("bad filter weight in %s line %d: '%s'", fi, n, buf)); - Exit(); + Exit(1); } for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { @@ -200,7 +200,7 @@ else { loge (("bad filter option in %s line %d: '%s'", fi, n, buf)); - Exit(); + Exit(1); } } strStripEOL(pat); @@ -222,7 +222,7 @@ char errbuf[MAX_LINE]; regerror(err_code, &f->preg, errbuf, sizeof errbuf); loge (("bad regular expression in %s line %d: %s", fi, n, errbuf)); - Exit(); + Exit(1); } #endif if (feof(fp) || ferror(fp)) @@ -231,7 +231,7 @@ if (!fc->filter) { loge (("filter file %s contained no filters!", fi)); - Exit(); + Exit(1); } if (!filter_list_index) { Index: nntpcache/article.c diff -u nntpcache/article.c:1.2 nntpcache/article.c:1.3 --- nntpcache/article.c:1.2 Wed Jul 9 13:51:15 1997 +++ nntpcache/article.c Thu Jul 10 11:23:08 1997 @@ -306,7 +306,7 @@ break; default: loge(("strange flow")); - Exit(); + Exit(1); } if (getbyid) /* dumb, but that is how inn does it */ emitf ("%s %d %s <%s>\r\n", m, artno, c, msgid); @@ -701,8 +701,16 @@ if (!f_filt) { emit_follows(type, artno, msgid, getbyid); /* 221 52 <839359140.253541@suburbia.net> head etc */ + Stats->article_this_group++; if (type==c_head || type == c_article) + { + if (type==c_head) + { + Stats->head_proxy++; + Stats->head_proxy_bytes += art_stack->used - 1; + } emit(art_stack->data); /* emit the head */ + } } if (type == c_body || type == c_article) { @@ -736,8 +744,19 @@ return FALSE; } emit_follows(type, artno, msgid, getbyid); + Stats->article_this_group++; if (type != c_stat) + { + if (type==c_article) + { + Stats->article_proxy++; + Stats->article_proxy_bytes += art_stack->used - 1; + } else { + Stats->body_proxy++; + Stats->body_proxy_bytes += art_stack->used - head_len - 1; + } emit ((type == c_body && !CurrentScfg->article_timeout)? art_stack->data+head_len+2: art_stack->data); + } } if (type != c_stat) emitrn ("."); @@ -836,27 +855,42 @@ emit_follows(type, artno, msgid, getbyid); switch (type) { + int wsize; + case c_article: fflush(clientout); /* keep fd and fh in-sync */ - write (fileno(clientout), buf, len); /* avoid buffering, push it out in one hit */ + /* avoid buffering, push it out in one hit */ + wsize = write (fileno(clientout), buf, len); + Stats->client_write_bytes += wsize; + Stats->article_proxy_bytes += wsize; + Stats->article_proxy++; break; case c_head: - fwrite (buf, body? body-2-buf: len, 1, clientout); /* head's tend to be small */ + /* head's tend to be small */ + wsize = fwrite (buf, body? body-2-buf: len, 1, clientout); + Stats->client_write_bytes += wsize; + Stats->head_proxy_bytes += wsize; + Stats->head_proxy++; break; case c_body: /* bodies can be large or small */ if (buf+len-body > 1024) { fflush(clientout); /* keep fd and fh in-sync */ - write (fileno(clientout), body, buf+len-body); /* avoid buffering, push it out in one hit */ + /* avoid buffering, push it out in one hit */ + wsize = write (fileno(clientout), body, buf+len-body); } else - fwrite (body, buf+len-body, 1, clientout); + wsize = fwrite (body, buf+len-body, 1, clientout); + Stats->client_write_bytes += wsize; + Stats->body_proxy_bytes += wsize; + Stats->body_proxy++; break; case c_stat: break; default: break; } + Stats->article_this_group; if (munmap(buf, len)!=0) loge (("couldn't munmap %s (%d length)", artfile, len)); if (type != c_stat) Index: nntpcache/group.c diff -u nntpcache/group.c:1.1.1.1 nntpcache/group.c:1.2 --- nntpcache/group.c:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/group.c Thu Jul 10 11:23:08 1997 @@ -239,6 +239,11 @@ return FALSE; } Stats->group++; + if (Stats->article_this_group && CurrentGroupScfg->group) + log (("%s group %s %d", ClientHostNormal, + CurrentGroupScfg->group, Stats->article_this_group)); + Stats->article_this_group = 0; + if (!safeGroup(attempted_group)) { emitrn (NNTP_NOSUCHGROUP); Index: nntpcache/history.c diff -u nntpcache/history.c:1.1.1.1 nntpcache/history.c:1.2 --- nntpcache/history.c:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/history.c Thu Jul 10 11:23:09 1997 @@ -272,7 +272,7 @@ if (chdir(con.cacheDir)<0 || !hisOpen () || stat (con.historyFile, &st) < 0) { loge (("fatal error: couldn't open/stat %s", con.historyFile)); - Exit (); + Exit (1); } if (st.st_size < con.hisHighWater) return TRUE; @@ -288,7 +288,7 @@ if (msg) { loge (("couldn't prune history (%s)", msg)); - Exit (); /* seriously suffering */ + Exit (1); /* seriously suffering */ } return TRUE; /* hisPruneDbz leaves con.historyFile open */ } Index: nntpcache/ipc.c diff -u nntpcache/ipc.c:1.2 nntpcache/ipc.c:1.3 --- nntpcache/ipc.c:1.2 Wed Jul 9 13:51:15 1997 +++ nntpcache/ipc.c Thu Jul 10 11:23:09 1997 @@ -24,8 +24,10 @@ unlink (f); return FALSE; } else - *Stats = st; + memcpy(Stats, &st, sizeof st); } + else + return FALSE; close (fd); return TRUE; } @@ -211,7 +213,7 @@ #if 0 if (*serv) { - Exit (); + Exit (1); /* find server stats TODO */ } else #endif @@ -225,6 +227,7 @@ case IPC_STATS: { int *i, *o; + unsigned long *ii, *oo; struct stats *p = (struct stats *) buf; if (cc < sizeof *p) { @@ -234,7 +237,9 @@ for (o = &Stats->active_len, i = &p->active_len; i <= (int *) &p->newsgroups_entries; o++, i++) if (*i) *o = *i; - for (o = &Stats->server_connects, i = &p->server_connects; i < (int *) &p->servername; *o++ += *i++) ; /* add */ + for (o = &Stats->server_connects, i = &p->server_connects; i < (int *) &p->client_user_cpu; *o++ += *i++) ; /* add */ + for (oo = &Stats->client_user_cpu, ii = &p->client_user_cpu; + ii < (unsigned long *) &p->servername; *oo++ += *ii++) ; /* add */ break; } #ifdef GRRR Index: nntpcache/ipc.h diff -u nntpcache/ipc.h:1.1.1.1 nntpcache/ipc.h:1.2 --- nntpcache/ipc.h:1.1.1.1 Thu Jun 19 12:23:57 1997 +++ nntpcache/ipc.h Thu Jul 10 11:23:09 1997 @@ -114,6 +114,7 @@ int article_cached_bytes; int article_cache; int article_cache_bytes; + int article_this_group; int head_cache; int head_cache_bytes; int head_cached; @@ -128,5 +129,7 @@ int body_proxy_bytes; int body_msgid; int body_artnum; + unsigned long client_user_cpu; + unsigned long client_syst_cpu; char servername[1]; /* nul if totall */ }; Index: nntpcache/nntpcache.c diff -u nntpcache/nntpcache.c:1.4 nntpcache/nntpcache.c:1.5 --- nntpcache/nntpcache.c:1.4 Wed Jul 9 13:51:16 1997 +++ nntpcache/nntpcache.c Thu Jul 10 11:23:09 1997 @@ -89,13 +89,13 @@ errno = 0; logw (("caught SIGTERM or SIGINT..syncing database...syncing disks...exiting")); } - Exit (); + Exit (1); } static RETSIGTYPE sigsegv (int sig) { loge (("SIGSEGV!")); - Exit (); + Exit (1); } static RETSIGTYPE sigusr1 (int sig) @@ -122,7 +122,7 @@ { emitf ("%d Timeout after %s, closing connection.\r\n", NNTP_TEMPERR_VAL, nnitod(con.idleTimeout)); log (("client idled out after %s", nnitod(con.idleTimeout))); - Exit (); + Exit (1); } static void check_child () @@ -153,8 +153,9 @@ signal (SIGCHLD, sigchld); } -X (void Exit ()) +X (void Exit (int code)) { + flush (); if (!Daemon || InDaemon) { dbzsync (); @@ -165,6 +166,23 @@ unlink (PidFile); sync (); } + } else { + struct tms buffer; + + if (Stats->article_this_group && CurrentGroupScfg->group) + log (("%s group %s %d", ClientHostNormal, + CurrentGroupScfg->group, Stats->article_this_group)); + log (("%s exit articles %d groups %d", ClientHostNormal, + (Stats->article_proxy + Stats->article_proxy + Stats->article_proxy), + Stats->group)); + times(&buffer); + Stats->client_user_cpu = buffer.tms_utime + buffer.tms_cutime; + Stats->client_syst_cpu = buffer.tms_stime + buffer.tms_cstime; + log (("%s times user %.2f system %.2f elapsed %d.00", + ClientHostNormal, + ((double) Stats->client_user_cpu/(double) HZ), + ((double) Stats->client_syst_cpu/(double) HZ), + (time(NULL) - Stats->time_client_started))); } if (Daddy >= 0) { @@ -176,14 +194,14 @@ mmalloc_detach (Mbase); #endif closelog (); - exit (1); + exit (code); } static RETSIGTYPE sigpipe (int sig) { signal (SIGPIPE, SIG_IGN); /* syslog can cause a SIGPIPE ! */ logd (("client disconnected before QUIT ACK")); - Exit (); + Exit (1); } static bool load_config (char *file) @@ -260,7 +278,7 @@ if (ferror(fp)) { loge (("error reading groups config from %s", file)); - Exit(); + Exit(1); } if (!list) { @@ -382,7 +400,7 @@ if (ferror(fp)) { loge (("error reading servers config from %s", file)); - Exit(); + Exit(1); } if (!list) { @@ -413,11 +431,11 @@ if (chdir (con.chrootDir) != 0 || chroot (".") != 0) { loge (("unable to chroot(\"%s\")", con.chrootDir)); - Exit(); + Exit(1); } #else loge (("no chroot() call available on this system")); - Exit(); + Exit(1); #endif } @@ -428,7 +446,7 @@ if (!ret) { loge (("mmalloc in %s failed", con.mmapFile)); - Exit(); + Exit(1); } return ret; #else @@ -443,7 +461,7 @@ if (!ret) { loge (("mcalloc in %s failed", con.mmapFile)); - Exit(); + Exit(1); } return ret; #else @@ -466,7 +484,7 @@ void bad_mmalloc() { loge (("Memory corrupt")); - Exit(); + Exit(1); } static void init_mmalloc(POINTER *m) @@ -516,7 +534,7 @@ if (fd<0) { loge (("unable to open %s", con.mmapFile)); - Exit(); + Exit(1); } } else f_cleanSlate = FALSE; @@ -527,7 +545,7 @@ if (fd<0 || f_retried) { loge (("couldn't attach mmap() region. abort.")); - Exit(); + Exit(1); } loge (("mmap() attach to %s failed (probably corrupted...removing it and trying again)", con.mmapFile)); unlink(con.mmapFile); @@ -545,7 +563,7 @@ if (!Ni) { loge (("invalid getkey/setkey in %s", con.mmapFile)); - Exit(); + Exit(1); } #else Ni=Scalloc(1, sizeof *Ni); @@ -568,14 +586,14 @@ { loge (("unable to set gid to %d", gid)); #ifndef DEBUG - Exit (); + Exit (1); #endif } if (setuid (uid) == -1) { loge (("unable to set uid to %d", uid)); #ifndef DEBUG - Exit (); + Exit (1); #endif } } @@ -707,7 +725,7 @@ if (chdir (con.configDir) == -1) { loge (("couldn't set cwd to %s", con.configDir)); - Exit (); + Exit (1); } if (!load_config (config_file)) Exit (1); @@ -744,7 +762,7 @@ if (chdir (con.configDir) == -1) { loge (("couldn't set cwd to %s", con.configDir)); - Exit (); + Exit (1); } logd(("cwd now %s", con.configDir)); if (!load_servers (con.serversFile)) @@ -757,13 +775,13 @@ if (!(pw = getpwnam (con.user))) { loge (("configuration error: no such user '%s'", con.user)); - Exit (); + Exit (1); } uid = pw->pw_uid; if (!(gr = getgrnam (con.group))) { loge (("configuration error: no such group '%s'", con.group)); - Exit (); + Exit (1); } gid = gr->gr_gid; if (con.chroot) @@ -778,7 +796,7 @@ if (chdir (con.cacheDir) == -1) { loge (("couldn't set cwd to %s", con.cacheDir)); - Exit (); + Exit (1); } logd(("cwd now %s", con.cacheDir)); signal (SIGTERM, sigterm); @@ -811,7 +829,7 @@ if (daemon_port == -1) { loge (("couldn't get socket()")); - Exit (); + Exit (1); } setsockopt (daemon_port, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof yes); @@ -820,7 +838,7 @@ if (bind (daemon_port, (struct sockaddr *) in, sizeof *in) == -1) { loge (("couldn't bind %s", con.bindAddr)); - Exit (); + Exit (1); } drop_priv(uid, gid); listen (daemon_port, 50); @@ -1017,7 +1035,7 @@ { emitf ("%d access denied <%s>, you do not have connect permissions in the %s file.\r\n", NNTP_ACCESS_VAL, ClientHost, con.accessFile); log (("refused connect from %s (%s)", ClientHost, ClientHostAddr)); - Exit (); + Exit (1); } if (con.contentFilters) { @@ -1035,7 +1053,7 @@ } signal(SIGALRM, sigalrm); alarm(con.idleTimeout); - log (("connect from %s (%s)", ClientHost, ClientHostAddr)); + log (("%s connect from %s (%s)", ClientHostNormal, ClientHostRFC931, ClientHostAddr)); setproctitle("%s: starting", ClientHost); emitf ("%d %s NNTPcache server V%s %s ready (posting %s).\r\n", gauth->post? NNTP_POSTOK_VAL: NNTP_NOPOSTOK_VAL, Host, VERSION, __DATE__, gauth->post? "ok": "not permitted"); flush (); @@ -1053,7 +1071,7 @@ if (!Get (buf, sizeof buf)) { logd (("client disconnected before QUIT")); - Exit (); + Exit (1); } if (con.statistics) Stats->client_read_bytes += strlen(buf); @@ -1196,20 +1214,6 @@ } setproctitle("%s closing", ClientHost); end: - flush (); - if (!Daemon || InDaemon) - { - dbzsync (); - dbmclose (); - sync (); - if (InDaemon) - unlink (PidFile); - } - if (Daddy >= 0) - { - PutStats (Stats); - close (Daddy); - } - closelog (); - exit (0); /* we let the kernel close any open fd's */ + Exit(0); + exit(0); /* Prevents complaints from compiler! */ } Index: nntpcache/post.c diff -u nntpcache/post.c:1.1.1.1 nntpcache/post.c:1.2 --- nntpcache/post.c:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/post.c Thu Jul 10 11:23:09 1997 @@ -43,7 +43,7 @@ { int cc=Get(bfr, sizeof bfr); if (cc<1) - Exit(); + Exit(1); bytes += cc; if (!body) { Index: nntpcache/standard.h diff -u nntpcache/standard.h:1.1.1.1 nntpcache/standard.h:1.2 --- nntpcache/standard.h:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/standard.h Thu Jul 10 11:23:09 1997 @@ -19,6 +19,7 @@ #include <string.h> #include <syslog.h> #include <ctype.h> +#include <sys/times.h> #ifndef LOG_NEWS # ifdef NEWS_NOTICE # define LOG_NEWS NEWS_NOTICE Index: nntpcache/stats.c diff -u nntpcache/stats.c:1.2 nntpcache/stats.c:1.3 --- nntpcache/stats.c:1.2 Wed Jul 9 13:51:16 1997 +++ nntpcache/stats.c Thu Jul 10 11:23:09 1997 @@ -29,6 +29,8 @@ emitf("\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes)); emitf("\tIPC messages from children: %24d\r\n", s->ipc_messages_in); emitf("\tIPC messages from children (bytes): %24s\r\n", c(s->ipc_messages_in_bytes)); + emitf("\tCPU Usage (User) in children: %23.2fs\r\n", ((double) s->client_user_cpu/(double) HZ)); + emitf("\tCPU Usage (System) in children: %23.2fs\r\n", ((double) s->client_syst_cpu/(double) HZ)); emitf("\tTotal time elapsed in children: %24s\r\n", nnitod(s->client_elapsed)); emitf("\tDatabase stores: %24d\r\n", s->dbz_stores); emitf("\tDatabase fetches: %24d\r\n", s->dbz_fetches); Index: nntpcache/libproff/utils.c diff -u nntpcache/libproff/utils.c:1.1.1.1 nntpcache/libproff/utils.c:1.2 --- nntpcache/libproff/utils.c:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/libproff/utils.c Thu Jul 10 11:23:09 1997 @@ -83,7 +83,7 @@ if (!ret) { loge (("mmalloc in %s failed", con.mmapFile)); - Exit(); + Exit(1); } return ret; } @@ -104,7 +104,7 @@ if (!ret) { loge (("mcalloc in %s failed", con.mmapFile)); - Exit(); + Exit(1); } return ret; } Index: nntpcache/mmalloc/README.osf diff -u nntpcache/mmalloc/README.osf:1.1.1.1 nntpcache/mmalloc/README.osf:1.2 --- nntpcache/mmalloc/README.osf:1.1.1.1 Thu Jun 19 12:23:58 1997 +++ nntpcache/mmalloc/README.osf Thu Jul 10 11:23:09 1997 @@ -85,7 +85,7 @@ ! static void bad_mmalloc() { loge (("Memory currupt")); - Exit(); + Exit(1); --- 475,481 ---- } @@ -93,7 +93,7 @@ ! void bad_mmalloc() { loge (("Memory currupt")); - Exit(); + Exit(1); *************** *** 610,616 **** bool f_swap_child = FALSE;
[ Nigel.Metheringham@theplanet.net - Systems Software Engineer ] [ Tel : +44 113 251 6012 Fax : +44 113 224 0003 ] [ Friends don't let friends use sendmail! ]