summaryrefslogtreecommitdiffabout
path: root/src/stat.c
authorSergey Poznyakoff <gray@gnu.org.ua>2009-04-24 08:02:35 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2009-04-24 08:02:35 (GMT)
commitc36ee7102c3095f70e8db52aa55046c1393ff4cd (patch) (side-by-side diff)
treee21b479c6e1d9c4b1c2fc8e6f0eed515b0588fe7 /src/stat.c
parent0d24087bca70de572cda0e35b91678816c5d9b40 (diff)
downloadtagr-c36ee7102c3095f70e8db52aa55046c1393ff4cd.tar.gz
tagr-c36ee7102c3095f70e8db52aa55046c1393ff4cd.tar.bz2
Fix statistics gathering algorithm. Start implementing drawing functions.
* src/output.c: New file. * src/Makefile.am (tagr_SOURCES): Add output.c * src/graph.c (draw_graph): New function. * src/main.c (mkfilename): Allow for suffix=NULL * src/report.c (tr_init): Set queue sizes to exactly the number of the corresponding samples. (update_output): New function. (rebuild): Implement * src/stat.c (interpolate): Avoid interpolation if time span is less than the step. Use queue_put to store the data and always call the overflow procedure, if supplied. (overflow): Fix condition. (compute_avg): New function. (ovf_monthly, ovf_weekly, ovf_daily): Add verbose diagnostics. (_convert): Additional argument: overflow function. (convert_yearly, convert_monthly, convert_weekly): Compute the average. Add verbose diagnostics. (convert_daily): Add verbose diagnostics. * src/tagr.h (update_output, draw_graph): New protos.
Diffstat (limited to 'src/stat.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/stat.c78
1 files changed, 64 insertions, 14 deletions
diff --git a/src/stat.c b/src/stat.c
index 4c1d434..a7bd2c1 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -41,17 +41,28 @@ interpolate (queue_t *q,
struct traffic_record *tr)
{
time_t next;
+ struct traffic_history th;
+ if (now - last_time <= step)
+ {
+ th.inrate = inrate;
+ th.outrate = outrate;
+ verbose (3, "Insert %lu %g %g", next, th.inrate, th.outrate);
+ queue_put (q, &th);
+ if (ovf)
+ ovf (&th, tr, now);
+ return;
+ }
+
for (next = last_time + step; next <= now; next += step)
{
- struct traffic_history th;
-
th.inrate = (inrate - last_rates->inrate) * (next - last_time)
/ interval + last_rates->inrate;
th.outrate = (outrate - last_rates->outrate) * (next - last_time)
/ interval + last_rates->outrate;
verbose (3, "Insert %lu %g %g", next, th.inrate, th.outrate);
- if (queue_xchg (q, &th) && ovf)
+ queue_put (q, &th);
+ if (ovf)
ovf (&th, tr, now);
}
}
@@ -66,7 +77,7 @@ overflow (struct traffic_history *th,
int maxcount,
int step)
{
- if (now - avg->time > step)
+ if (now - avg->time >= step)
{
struct traffic_history *lastp = queue_get_tail (q);
if (lastp)
@@ -99,22 +110,28 @@ overflow (struct traffic_history *th,
int
ovf_monthly (struct traffic_history *th, struct traffic_record *tr, time_t now)
{
+ verbose (2, "begin overflow_monthly %lu %g %g", now, th->inrate, th->outrate);
overflow (th, tr, now, NULL, &tr->year_avg, &tr->year_hist,
YEAR_COUNT, YEAR_SAMPLE);
+ verbose (2, "end overflow_monthly");
}
int
ovf_weekly (struct traffic_history *th, struct traffic_record *tr, time_t now)
{
+ verbose (2, "begin overflow_weekly %lu %g %g", now, th->inrate, th->outrate);
overflow (th, tr, now, ovf_monthly, &tr->month_avg, &tr->month_hist,
MONTH_COUNT, MONTH_SAMPLE);
+ verbose (2, "end overflow_daily");
}
int
ovf_daily (struct traffic_history *th, struct traffic_record *tr, time_t now)
{
+ verbose (2, "begin overflow_daily %lu %g %g", now, th->inrate, th->outrate);
overflow (th, tr, now, ovf_weekly, &tr->week_avg, &tr->week_hist,
WEEK_COUNT, WEEK_SAMPLE);
+ verbose (2, "end overflow_daily");
}
void
@@ -161,16 +178,35 @@ update_stats (SD *sd, struct traffic_record *tr)
+
+static void
+compute_avg (struct avg_acc *avg, queue_t *q, struct last_sample *last)
+{
+ int i, n = queue_count (q);
+ avg->inrate = avg->outrate = 0;
+ avg->count = n;
+
+ for (i = 0; i < n; i++)
+ {
+ struct traffic_history *th = queue_get_ptr (q, i);
+ avg->inrate += th->inrate;
+ avg->outrate += th->outrate;
+ }
+ avg->inrate /= n;
+ avg->outrate /= n;
+ avg->time = last->time;
+}
+
#define hist_rec last_sample
static void
-_convert (queue_t *q,
+_convert (queue_t *q, ovf_t ovf,
struct traffic_record *tr, struct hist_rec *hist, size_t count,
time_t sample_interval)
{
size_t i;
struct hist_rec *hp;
-
+
tr->last.time = hist[count-1].time - sample_interval;
for (hp = hist + count - 1; hp >= hist; hp--)
{
@@ -181,7 +217,7 @@ _convert (queue_t *q,
interval = hp->time - tr->last.time;
inrate = (double) hp->in;
outrate = (double) hp->out;
-
+
if (interval == 0)
{
logmsg (L_ERR, "Ignoring zero interval");
@@ -196,7 +232,7 @@ _convert (queue_t *q,
&tr->last_rates,
interval,
inrate, outrate,
- NULL, tr);
+ ovf, tr);
}
else
{
@@ -212,37 +248,51 @@ _convert (queue_t *q,
tr->last.out = hp->out;
tr->last_rates.inrate = inrate;
tr->last_rates.outrate = outrate;
- }
+ }
}
static void
convert_yearly (struct traffic_record *tr, struct hist_rec *hp, size_t count)
{
- _convert (&tr->year_hist, tr, hp, YEAR_COUNT + 1, YEAR_SAMPLE);
+ verbose (2, "begin convert_yearly");
+ _convert (&tr->year_hist, NULL, tr,
+ hp, count, YEAR_SAMPLE);
+ compute_avg (&tr->year_avg, &tr->year_hist, &tr->last);
+ verbose (2, "end convert_yearly");
}
static void
convert_monthly (struct traffic_record *tr, struct hist_rec *hp, size_t count)
{
+ verbose (2, "begin convert_monthly");
if (count > MONTH_COUNT+1)
convert_yearly (tr, hp + MONTH_COUNT + 1, count - (MONTH_COUNT + 1));
- _convert (&tr->month_hist, tr, hp, MONTH_COUNT + 1, MONTH_SAMPLE);
+ _convert (&tr->month_hist, ovf_monthly, tr,
+ hp, MONTH_COUNT + 1, MONTH_SAMPLE);
+ compute_avg (&tr->month_avg, &tr->month_hist, &tr->last);
+ verbose (2, "end convert_monthly");
}
static void
convert_weekly (struct traffic_record *tr, struct hist_rec *hp, size_t count)
{
+ verbose (2, "begin convert_weekly");
if (count > WEEK_COUNT+1)
convert_monthly (tr, hp + WEEK_COUNT + 1, count - (WEEK_COUNT + 1));
- _convert (&tr->week_hist, tr, hp, WEEK_COUNT + 1, WEEK_SAMPLE);
+ _convert (&tr->week_hist, ovf_weekly,
+ tr, hp, WEEK_COUNT + 1, WEEK_SAMPLE);
+ compute_avg (&tr->week_avg, &tr->week_hist, &tr->last);
+ verbose (2, "end convert_weekly");
}
static void
convert_daily (struct traffic_record *tr, struct hist_rec *hp, size_t count)
{
+ verbose (2, "begin convert_daily");
if (count > DAY_COUNT+1)
convert_weekly (tr, hp + DAY_COUNT + 1, count - (DAY_COUNT + 1));
- _convert (&tr->day_hist, tr, hp, DAY_COUNT + 1, DAY_SAMPLE);
+ _convert (&tr->day_hist, ovf_daily, tr, hp, DAY_COUNT + 1, DAY_SAMPLE);
+ verbose (2, "end convert_daily");
}
static void
@@ -255,7 +305,7 @@ convert_stats (SD *sd, struct hist_rec *last,
tr_init (&tr);
convert_daily (&tr, hp, count);
-
+
read_db (sd, &trp);
*trp = tr;
trp->last = *last;

Return to:

Send suggestions and report system problems to the System administrator.