aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2005-11-23 19:34:13 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2005-11-23 19:34:13 +0000
commit7ce6f8b0537ba5d3f09fa1f31ed6337f5c21c2b5 (patch)
treed88110185952ee605aa1a1ad236093f3b6acdd6f
parente5e002ab7d1b2bb6ad414e45343e12464a5ee44d (diff)
downloadtagr-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.c262
1 files changed, 226 insertions, 36 deletions
diff --git a/stat.c b/stat.c
index 41226f9..c847550 100644
--- a/stat.c
+++ b/stat.c
@@ -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);
}
+

Return to:

Send suggestions and report system problems to the System administrator.