diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-11-23 19:34:13 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-11-23 19:34:13 +0000 |
commit | 7ce6f8b0537ba5d3f09fa1f31ed6337f5c21c2b5 (patch) | |
tree | d88110185952ee605aa1a1ad236093f3b6acdd6f | |
parent | e5e002ab7d1b2bb6ad414e45343e12464a5ee44d (diff) | |
download | tagr-7ce6f8b0537ba5d3f09fa1f31ed6337f5c21c2b5.tar.gz tagr-7ce6f8b0537ba5d3f09fa1f31ed6337f5c21c2b5.tar.bz2 |
(intepolate): Fixed typo (interpolate). All callers
updated. Fixed rates computation.
(update_stats): Lots of fixes.
(import): New function.
git-svn-id: file:///svnroot/tagr/trunk@68 7c378d0d-a4e4-4a64-9229-dfce8bfd23d4
-rw-r--r-- | stat.c | 262 |
1 files changed, 226 insertions, 36 deletions
@@ -20,18 +20,25 @@ # include <config.h> #endif #include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <glob.h> +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include <obstack.h> #include <tagr.h> typedef int (*ovf_t) (struct traffic_history *th, struct traffic_record *tr, time_t now); void -iterpolate (queue_t *q, - time_t step, time_t now, - time_t last_time, struct traffic_history *last_rates, - time_t interval, double inrate, double outrate, - ovf_t ovf, - struct traffic_record *tr) +interpolate (queue_t *q, + time_t step, time_t now, + time_t last_time, struct traffic_history *last_rates, + time_t interval, double inrate, double outrate, + ovf_t ovf, + struct traffic_record *tr) { time_t next; @@ -40,9 +47,10 @@ iterpolate (queue_t *q, struct traffic_history th; th.inrate = (inrate - last_rates->inrate) * (next - last_time) - / interval; + / interval + last_rates->inrate; th.outrate = (outrate - last_rates->outrate) * (next - last_time) - / interval; + / interval + last_rates->outrate; + verbose (3, "Insert %lu %g %g", next, th.inrate, th.outrate); if (queue_xchg (q, &th) && ovf) ovf (&th, tr, now); } @@ -62,19 +70,20 @@ overflow (struct traffic_history *th, { struct traffic_history *lastp = queue_get_tail (q); if (lastp) - iterpolate (q, - step, - now, - avg->time, - lastp, - now - avg->time, - avg->inrate, avg->outrate, - ovf, tr); + interpolate (q, + step, + now, + avg->time, + lastp, + now - avg->time, + avg->inrate, avg->outrate, + ovf, tr); else { struct traffic_history tmp; tmp.inrate = avg->inrate; tmp.outrate = avg->outrate; + verbose (3, "Insert %lu %g %g", now, tmp.inrate, tmp.outrate); queue_put (q, &tmp); } @@ -111,44 +120,225 @@ ovf_daily (struct traffic_history *th, struct traffic_record *tr, time_t now) void update_stats (SD *sd, struct traffic_record *tr) { - time_t now = time (NULL); time_t interval; double inrate, outrate; struct traffic_history *lastp = queue_get_tail (&tr->day_hist); + + interval = sd->t - tr->last.time; + if (interval == 0) + { + logmsg (L_ERR, "Ignoring zero interval"); + return; + } + inrate = (double) sd->in / interval; + outrate = (double) sd->out / interval; if (lastp) { /* Compute estimated rate for the recent interval */ - interval = now - tr->last.time; - inrate = (sd->in - tr->last.in) / interval; - outrate = (sd->out - tr->last.out) / interval; - - iterpolate (&tr->day_hist, - DAY_SAMPLE, - now, - tr->last.time, - &tr->last_rates, - interval, - inrate, outrate, - ovf_daily, tr); + + interpolate (&tr->day_hist, + DAY_SAMPLE, + sd->t, + tr->last.time, + &tr->last_rates, + interval, + inrate, outrate, + ovf_daily, tr); } - else if (tr->last.time) + else { struct traffic_history th; - interval = now - tr->last.time; - th.inrate = (sd->in - tr->last.in) / interval; - th.outrate = (sd->out - tr->last.out) / interval; + interval = sd->t - tr->last.time; + th.inrate = inrate; + th.outrate = outrate; queue_put (&tr->day_hist, &th); } - tr->last.time = now; + tr->last.time = sd->t; tr->last.in = sd->in; tr->last.out = sd->out; tr->last_rates.inrate = inrate; tr->last_rates.outrate = outrate; } + + +#define hist_rec last_sample + +static void +convert_stats (SD *sd, struct hist_rec *last, + struct hist_rec *hp, size_t count) +{ + size_t i; + struct traffic_record *trp, tr; + + memset (&tr, 0, sizeof tr); + tr_init (&tr); + tr.last.time = hp[count-1].time - 300; + for (i = count - 1; i+1 > 0; i--) + { + sd->t = hp[i].time; + sd->in = hp[i].in * 300; + sd->out = hp[i].out * 300; + verbose (3, "Data %lu %lu %lu", sd->t, sd->in, sd->out); + update_stats (sd, &tr); + } + + read_db (sd, &trp); + *trp = tr; + trp->last = *last; + write_db (sd, trp); + free (trp); +} + +static int +import_log (const char *name) +{ + FILE *fp; + int rc = 0; + struct obstack stk; + struct hist_rec last, hist, *hp; + unsigned long inmax, outmax; + size_t count = 0; + char *buf = NULL; + size_t bufsize = 0; + size_t line = 1; + time_t cur; + + fp = fopen (name, "r"); + if (!fp) + { + logmsg (L_ERR, "cannot open `%s': %s", name, strerror (errno)); + return 1; + } + verbose (2, "Importing %s", name); + + + if (fscanf (fp, "%ld %lu %lu\n", &last.time, &last.in, &last.out) != 3) + { + logmsg (L_ERR, "%s:1: Inexpected number of fields", name); + fclose (fp); + return 1; + } + cur = last.time; + + obstack_init (&stk); + while (getline (&buf, &bufsize, fp) > 0) + { + int i; + unsigned long rd[5]; + + line++; + + if (sscanf (buf, "%lu %lu %lu %lu %lu", + &rd[0], &rd[1], &rd[2], &rd[3], &rd[4]) < 5) + { + rd[3] = rd[1]; + rd[4] = rd[2]; + } + + for (i = 0; i <= 4; i++) + rd[i] = rd[i] < 0 ? 0 : rd[i]; + + hist.time = rd[0]; + hist.in = rd[1]; + hist.out = rd[2]; + if (inmax < rd[3]) + inmax = rd[3]; + if (inmax < hist.in) + inmax = hist.in; + if (outmax < rd[4]) + outmax = rd[4]; + if (outmax < hist.out) + outmax = hist.out; + + if (hist.time > cur) + { + logmsg (L_WARNING, "%s:%lu: is corrupted", name, line); + break; + } + obstack_grow (&stk, &hist, sizeof (hist)); + count++; + } + fclose (fp); + free (buf); + + hp = obstack_finish (&stk); + if (count) + { + SD *sd; + + char *p = strrchr (name, '/'); + char *base = xstrdup (p ? p + 1 : name); + p = strrchr (base, '.'); + if (p) + *p = 0; + + sd = find_router (base); + if (!sd) + { + logmsg (L_ERR, "cannot find router `%s'", base); + rc = 1; + } + else + convert_stats (sd, &last, hp, count); + } + + obstack_free (&stk, NULL); + return rc; +} + void -import (const char *dir) +import (const char *dirname) { - die (3, "Import is not yet implemented"); + size_t count = 0; + struct stat st; + + if (stat (dirname, &st)) + die (3, "cannot stat file `%s': %s", dirname, strerror (errno)); + else if (S_ISREG (st.st_mode)) + { + open_db (); + if (import_log (dirname) == 0) + count++; + close_db (); + } + else if (S_ISDIR (st.st_mode)) + { + char *pattern; + glob_t gl; + size_t i; + int rc; + + pattern = mkfilename (dirname, "*/", "*.log"); + rc = glob (pattern, 0, NULL, &gl); + free (pattern); + + switch (rc) + { + case 0: + open_db (); + for (i = 0; i < gl.gl_pathc; i++) + if (import_log (gl.gl_pathv[i]) == 0) + count++; + globfree (&gl); + close_db (); + break; + + case GLOB_NOSPACE: + die (3, "cannot scan directory: %s", strerror (ENOMEM)); + + case GLOB_ABORTED: + die (3, "scanning aborted"); + + case GLOB_NOMATCH: + break; + + default: + die (3, "cannot scan directory `%s'", dirname); + } + } + + verbose (1, "Number of imported log files: %d", count); } + |