diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-11 22:45:37 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-11 22:45:37 +0000 |
commit | eb79907f63b7985751849d7a13e13879b6b8da9e (patch) | |
tree | eefbe4fc827242cb32f18a1ef0a4ffb4772630cd /src/report.c | |
parent | 156b2a34fbc4dd3215c5b8cc2cc326f56dfb7df8 (diff) | |
download | tagr-eb79907f63b7985751849d7a13e13879b6b8da9e.tar.gz tagr-eb79907f63b7985751849d7a13e13879b6b8da9e.tar.bz2 |
Reorganize project directory layout.
* README-hacking: New file.
* src: New directory
* src/Makefile.am: New file.
* graph.c, readconfig.c, tagr.h, log.c, report.h,
queue.c: Move to src
* main.c: Move to src, fix a minor bug in main.
* html.l: Move to src/html.lex.l.
* html.y: Move to src/html.gram.y.
* lib/argcv.c, lib/argcv.h: Move to src.
* config, INSTALL: Remove
* README_hacking: New file.
* configure.ac, Makefile.am: Update for new gnulib and new
directory structure.
* bootstrap: Update from gnulib.
* gnulib.modules: New file.
* bootstrap.conf: New file.
git-svn-id: file:///svnroot/tagr/trunk@89 7c378d0d-a4e4-4a64-9229-dfce8bfd23d4
Diffstat (limited to 'src/report.c')
-rw-r--r-- | src/report.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/report.c b/src/report.c new file mode 100644 index 0000000..13c4d69 --- /dev/null +++ b/src/report.c @@ -0,0 +1,241 @@ +/* This file is part of tagr. + Copyright (C) 2000, 2005, Max Bouglacoff, Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <tagr.h> +#include <report.h> +#include <gdbm.h> + +static char *dbname; +static GDBM_FILE dbf; + +static void +tagr_db_report (char *str) +{ + logmsg (L_CRIT, "%s: %s", dbname, str); +} + +void +open_db () +{ + dbname = xmalloc (strlen (basedir) + 1 + sizeof (TAGR_DBNAME)); + strcpy (dbname, basedir); + strcat (dbname, "/"); + strcat (dbname, TAGR_DBNAME); + dbf = gdbm_open (dbname, 0, GDBM_WRCREAT, TAGR_DBMODE, tagr_db_report); + if (dbf == NULL) + { + logmsg (L_ERR, "Cannot open database %s: %s", + dbname, gdbm_strerror (gdbm_errno)); + exit (1); + } +} + +void +close_db () +{ + gdbm_close (dbf); + free (dbname); + dbname = NULL; +} + +/* FIXME: Spurious initialization of .size member. */ +void +tr_init (struct traffic_record *tr) +{ + tr->day_hist.queue = tr->history; + tr->day_hist.size = DAY_COUNT + 2; + + tr->week_hist.queue = tr->day_hist.queue + tr->day_hist.size; + tr->week_hist.size = WEEK_COUNT + 2; + + tr->month_hist.queue = tr->week_hist.queue + tr->week_hist.size; + tr->month_hist.size = MONTH_COUNT + 2; + + tr->year_hist.queue = tr->month_hist.queue + tr->month_hist.size; + tr->year_hist.size = YEAR_COUNT + 2; +} + +static void +_read_db (datum key, struct traffic_record **tr) +{ + datum content; + + content = gdbm_fetch (dbf, key); + if (content.dptr == NULL) + logmsg (L_NOTICE, "Record for %*.*s not found", key.dsize, key.dsize, key.dptr); + else if (content.dsize != sizeof **tr) + { + logmsg (L_ERR, "Wrong record size for %*.*s: %lu", + key.dsize, key.dsize, key.dptr, content.dsize); + } + else + { + *tr = (struct traffic_record *) content.dptr; + tr_init (*tr); + return; + } + + logmsg (L_NOTICE, "Creating record for %*.*s", + key.dsize, key.dsize, key.dptr); + *tr = xmalloc (sizeof **tr); + memset (*tr, 0, sizeof **tr); + tr_init (*tr); +} + +void +read_db (SD *sd, struct traffic_record **tr) +{ + datum key; + datum content; + + key.dptr = sd->id; + key.dsize = strlen (sd->id); + _read_db (key, tr); +} + +void +write_db (SD *sd, struct traffic_record *tr) +{ + datum key; + datum content; + + key.dptr = sd->id; + key.dsize = strlen (sd->id); + + content.dsize = sizeof *tr; + content.dptr = (char *) tr; + + if (gdbm_store (dbf, key, content, GDBM_REPLACE)) + { + logmsg (L_ERR, "Failed to write data for %s: %s", + sd->id, gdbm_strerror (gdbm_errno)); + } +} + +static void +print_queue (const char *title, queue_t *q) +{ + int i, count; + + count = queue_count (q); + printf ("%s (%d entries):\n", title, count); + for (i = count - 1; i >= 0; i--) + { + struct traffic_history *th = queue_get_ptr (q, i); + printf("%d %g %g\n", count - i, th->inrate, th->outrate); + } +} + +static void +print_avg (const char *title, struct avg_acc *avg) +{ + char buf[512]; + strftime (buf, sizeof buf, "%c", localtime (&avg->time)); + + printf ("%s: %lu (%s) %u %g %g\n", + title, avg->time, buf, avg->count, avg->inrate, avg->outrate); +} + +static void +print_tr (datum key, struct traffic_record *tr) +{ + char buf[512]; + struct tm *tm; + int i, count; + + tm = localtime (&tr->last.time); + printf ("ID: %*.*s\n", key.dsize, key.dsize, key.dptr); + strftime (buf, sizeof buf, "%c", tm); + printf ("Last sample: %lu (%s) %lu %lu\n", + tr->last.time, buf, tr->last.in, tr->last.out); + + printf ("Last rates: %g %g\n", tr->last_rates.inrate, tr->last_rates.outrate); + print_queue ("Daily rates", &tr->day_hist); + + print_avg ("Weekly average", &tr->week_avg); + print_queue ("Weekly rates", &tr->week_hist); + + print_avg ("Monthly average", &tr->month_avg); + print_queue ("Monthly rates", &tr->month_hist); + + print_avg ("Yearly average", &tr->year_avg); + print_queue ("Yearly rates", &tr->year_hist); +} + +void +list_db () +{ + datum key; + datum content; + SD sd; + + open_db (); + key = gdbm_firstkey (dbf); + while (key.dptr) + { + struct traffic_record *tr; + datum nextkey = gdbm_nextkey (dbf, key); + _read_db (key, &tr); + print_tr (key, tr); + free (tr); + free (key.dptr); + key = nextkey; + } + close_db (); +} + +void +report (Stat *stat) +{ + SD *sd = find_router_id (stat->name); + + if (sd) + { + struct traffic_record *tr; + + sd->in = stat->in; + sd->out = stat->out; + sd->t = time (NULL); + read_db (sd, &tr); + update_stats (sd, tr); + write_db (sd, tr); + free (tr); + } + else + logmsg (L_WARNING, "%s not found in config", stat->name); +} + +void +rebuild () +{ + die (3, "Rebuild is not yet implemented"); +} |