src/stats.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- loadStats
- saveStats
- statsUpdateMaster
- print_stats
- PrintStats
/* $Id: stats.c,v 1.2 1998/08/02 20:35:04 proff Exp $
* $Copyright$
*/
#include "nglobal.h"
#include "article.h"
#include "stats.h"
#include "http.h"
#define bf bigToStr
EXPORT struct stats *Stats = NULL;
EXPORT void loadStats (char *f)
/* [<][>][^][v][top][bottom][index][help] */
{
int fd;
struct stats st;
Stats = XMmalloc (sizeof(*Stats));
fd = open (f, O_RDONLY);
if (fd >= 0)
{
if (read (fd, &st, sizeof st) != sizeof st)
{
loge (("statistics file '%s' corrupted...unlinking", f));
close (fd);
unlink (f);
} else
if (st.version != STATS_VERSION)
{
char buf[MAX_PATH];
sprintf (buf, "%s.%d", f, st.version);
loge (("statistics file '%s' version %d, require version %d...renaming old file to '%s'", f, st.version, STATS_VERSION, buf));
link(f, buf);
unlink(f);
} else
{
memcpy (Stats, &st, sizeof st);
close (fd);
goto good;
}
close (fd);
}
memset (Stats, 0, sizeof(*Stats));
Stats->statsStarted = time (NULL);
Stats->version = STATS_VERSION;
good:
Stats->invocations++;
Stats->clientsActive = 0;
Stats->task_high = 0;
Stats->masterStarted = time (NULL);
CS = &Stats->cache_stats[c_none];
}
EXPORT bool saveStats (char *f)
/* [<][>][^][v][top][bottom][index][help] */
{
int fd;
statsUpdateMaster ();
fd = open (f, O_WRONLY | O_CREAT, 0664);
if (write (fd, Stats, sizeof *Stats) != sizeof *Stats)
{
loge (("error during write of '%s'", f));
close (fd);
unlink (f);
return FALSE;
}
close (fd);
return TRUE;
}
EXPORT void statsUpdateMaster ()
/* [<][>][^][v][top][bottom][index][help] */
{
static unsigned long U, S;
static time_t T;
unsigned long u, s;
time_t t;
assert(Task);
if (Task->ti_state != nc_master)
return;
time(&t);
if (T != t)
{
struct tms tms;
times(&tms);
u = tms.tms_utime;
Stats->task_stats[Task->ti_state].cpu_user += u-U;
U = u;
s = tms.tms_stime;
Stats->task_stats[Task->ti_state].cpu_system += s-S;
S = s;
}
if (T == 0)
{
T = t;
}
else
{
if (t>T)
{
Stats->task_stats[Task->ti_state].elapsed += t-T;
T = t;
}
}
}
/* parameters to fprintf(clientout, ) are passed on the stack altogether, which means functions returning pointers to static variables don't work. */
#define c convMalloc
#define b c
static void print_stats (struct stats *s)
/* [<][>][^][v][top][bottom][index][help] */
{
#if 0
time_t ti=time(NULL);
int dif=ti-s->time_statistics_started;
/* keep initial \r\n -- used for head/body sep */
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: %24s\r\n", c(s->client_connects));
emitf("\tOutgoing server connections: %24s\r\n", c(s->server_connects));
emitf("\tOutgoing server connections (failed): %24s\r\n", c(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)))*100.0);
emitf("\tIPC messages to children: %24s\r\n", b(s->ipc_messages_out));
emitf("\tIPC messages to children (bytes): %24s\r\n", c(s->ipc_messages_out_bytes));
emitf("\tIPC messages from children: %24s\r\n", b(s->ipc_messages_in));
emitf("\tIPC messages from children (bytes): %24s\r\n", c(s->ipc_messages_in_bytes));
emitf("\tCPU Usage (User) in server: %23.2fs\r\n", ((double) s->server_user_cpu/(double) CLK_TCK));
emitf("\tCPU Usage (System) in server: %23.2fs\r\n", ((double) s->server_syst_cpu/(double) CLK_TCK));
emitf("\tCPU Usage (User) in update daemon: %23.2fs\r\n", ((double) s->update_user_cpu/(double) CLK_TCK));
emitf("\tCPU Usage (System) in update daemon: %23.2fs\r\n", ((double) s->update_syst_cpu/(double) CLK_TCK));
emitf("\tCPU Usage (User) in children: %23.2fs\r\n", ((double) s->client_user_cpu/(double) CLK_TCK));
emitf("\tCPU Usage (System) in children: %23.2fs\r\n", ((double) s->client_syst_cpu/(double) CLK_TCK));
emitf("\tTotal time elapsed in children: %24s\r\n", nnitod(s->client_elapsed));
emitf("\tDatabase stores: %24s\r\n", b(s->dbz_stores));
emitf("\tDatabase fetches: %24s\r\n", b(s->dbz_fetches));
emitf("\tDatabase size: %24s\r\n", c(s->dbz_len));
emitf("\tGROUP commands: %24s\r\n", b(s->group));
emitf("\tLISTGROUP commands: %24s\r\n", b(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: %24s\r\n", b(s->expire_articles));
emitf("\tPosts: %24s\r\n", b(s->posts));
emitf("\tPosts (crossposted): %24s\r\n", b(s->posts_cross));
emitf("\tPosts (failed): %24s\r\n", b(s->posts_failed));
emitf("\tPosts (bytes): %24s\r\n", c(s->posts_bytes));
emitf("\tIncoming crossposts: %24s\r\n", b(s->crossposts));
emitf("\tIncoming crossposts (bytes): %24s\r\n", c(s->crossposts_bytes));
#if 0
emitf("\
\r\n\
LISTS:\r\n\
\r\n\
List-name---- --out-of-cache -----into-cache hits --xfer-per-hour lines -length\r\n");
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));
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));
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));
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");
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));
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));
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));
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));
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));
#endif
convFree();
return;
#endif
}
EXPORT bool PrintStats()
/* [<][>][^][v][top][bottom][index][help] */
{
print_stats(Stats);
return TRUE;
}