diff options
author | Sergey Poznyakoff <gray@Pirx.gnu.org.ua> | 2009-04-28 16:27:03 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@Pirx.gnu.org.ua> | 2009-04-28 16:27:03 +0300 |
commit | 20d7f1d7e051c6b021a3f5d088985a74c3370b29 (patch) | |
tree | 5c5dc1c1b401e055096b8ec216a6bd97eb76a520 | |
parent | 29e4b3da0990aca9db232dc3ce0a57722ccf1cac (diff) | |
download | tagr-20d7f1d7e051c6b021a3f5d088985a74c3370b29.tar.gz tagr-20d7f1d7e051c6b021a3f5d088985a74c3370b29.tar.bz2 |
Store timestamps. Implement zero-unknown option.
* src/graph.c (draw_graph): Use timestamps from queue entries.
Implement zero_unknown_option.
* src/output.c: Store timestamps in traffic_history entries.
* src/readconfig.c (cb_monitor, cb_server): Fix checks for
empty ID.
(tagr_kw): New keyword cut-out-fraction.
(readconfig): Reset cut_out_fraction if it is < 1.0.
* src/report.c: Print timestamps.
* src/stat.c (cut_out_fraction): New variable.
(ovf_t, overflow): Remove (spurious now) arguments.
(interpolate, overflow, update_stats): Don't interpolate if
time interval between this sample and the lastly taken one
is greater than step * cut_out_fraction.
* src/tagr.h (TAGR_CUT_OUT): New define.
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | src/graph.c | 46 | ||||
-rw-r--r-- | src/output.c | 3 | ||||
-rw-r--r-- | src/readconfig.c | 16 | ||||
-rw-r--r-- | src/report.c | 23 | ||||
-rw-r--r-- | src/stat.c | 64 | ||||
-rw-r--r-- | src/tagr.h | 8 |
7 files changed, 113 insertions, 52 deletions
@@ -9,9 +9,10 @@ S: +OK accepted | |||
9 | C: QUIT | 9 | C: QUIT |
10 | S: +OK bye | 10 | S: +OK bye |
11 | 11 | ||
12 | * Zero-unknown option and interrupted data feeds | 12 | * Drawing interrupted data feeds |
13 | 13 | ||
14 | Decide what to do if a data feed gets interrupted. | 14 | What to do if zero-inknown is set to `false'? Currently, linear |
15 | interpolation is performed. | ||
15 | 16 | ||
16 | * Synchronous updates | 17 | * Synchronous updates |
17 | 18 | ||
diff --git a/src/graph.c b/src/graph.c index 8088773..1197a7d 100644 --- a/src/graph.c +++ b/src/graph.c | |||
@@ -90,6 +90,7 @@ draw_graph (FILE *fp, | |||
90 | int full_ysize = graph_ysize + graph_v_margin[0] + graph_v_margin[1]; | 90 | int full_ysize = graph_ysize + graph_v_margin[0] + graph_v_margin[1]; |
91 | grid_t grid; | 91 | grid_t grid; |
92 | unsigned long ymax = mon->max_rate; | 92 | unsigned long ymax = mon->max_rate; |
93 | time_t start; | ||
93 | 94 | ||
94 | yscale = (double) graph_ysize / ymax; | 95 | yscale = (double) graph_ysize / ymax; |
95 | xscale = (double) graph_xsize / xmax; | 96 | xscale = (double) graph_xsize / xmax; |
@@ -142,38 +143,65 @@ draw_graph (FILE *fp, | |||
142 | n = queue_count (dataq); | 143 | n = queue_count (dataq); |
143 | 144 | ||
144 | /* Incoming traffic */ | 145 | /* Incoming traffic */ |
145 | for (i = n - 1, x = 0; i > 0 && x < xmax; i--, x += xstep) | 146 | for (i = n - 1, start = 0; i > 0; i--) |
146 | { | 147 | { |
147 | struct traffic_history th, tnext; | 148 | struct traffic_history th, tnext; |
148 | 149 | ||
149 | scale_sample (mon, queue_get_ptr (dataq, i), &th); | 150 | scale_sample (mon, queue_get_ptr (dataq, i), &th); |
151 | if (start == 0) | ||
152 | start = th.time; | ||
150 | scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); | 153 | scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); |
154 | if (start - tnext.time > xmax) | ||
155 | break; | ||
156 | if (zero_unknown_option | ||
157 | && th.time - tnext.time > xstep * cut_out_fraction) | ||
158 | { | ||
159 | gdImageLine (graph, xtr (start - tnext.time), ytr (0), | ||
160 | xtr (start - tnext.time), ytr (tnext.inrate), i_in); | ||
161 | th.inrate = tnext.inrate = 0; | ||
162 | th.outrate = tnext.outrate = 0; | ||
163 | } | ||
164 | |||
151 | if (fill_incoming_option) | 165 | if (fill_incoming_option) |
152 | gdImageLine (graph, | 166 | gdImageLine (graph, |
153 | xtr (x), ytr (0), | 167 | xtr (start - th.time), ytr (0), |
154 | xtr (x), ytr (tnext.inrate), i_in); | 168 | xtr (start - th.time), ytr (tnext.inrate), i_in); |
155 | gdImageLine (graph, xtr (x), ytr (th.inrate), | 169 | gdImageLine (graph, xtr (start - th.time), ytr (th.inrate), |
156 | xtr (x + xstep), ytr (tnext.inrate), i_in); | 170 | xtr (start - tnext.time), ytr (tnext.inrate), i_in); |
157 | } | 171 | } |
158 | 172 | ||
159 | /* Outgoing traffic */ | 173 | /* Outgoing traffic */ |
160 | gdImageSetBrush (graph, brush_out); | 174 | gdImageSetBrush (graph, brush_out); |
161 | for (i = n - 1, x = 0; i > 0 && x < xmax; i--, x += xstep) | 175 | for (i = n - 1, start = 0; i > 0; i--) |
162 | { | 176 | { |
163 | struct traffic_history th, tnext; | 177 | struct traffic_history th, tnext; |
164 | 178 | ||
165 | scale_sample (mon, queue_get_ptr (dataq, i), &th); | 179 | scale_sample (mon, queue_get_ptr (dataq, i), &th); |
180 | if (start == 0) | ||
181 | start = th.time; | ||
166 | scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); | 182 | scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); |
183 | if (start - tnext.time > xmax) | ||
184 | break; | ||
167 | 185 | ||
168 | gdImageLine (graph, xtr (x), ytr (th.outrate), | 186 | if (zero_unknown_option |
169 | xtr (x + xstep), ytr (tnext.outrate), gdBrushed); | 187 | && th.time - tnext.time > xstep * cut_out_fraction) |
188 | { | ||
189 | gdImageLine (graph, xtr (start - tnext.time), ytr (0), | ||
190 | xtr (start - tnext.time), ytr (tnext.inrate), | ||
191 | gdBrushed); | ||
192 | th.inrate = tnext.inrate = 0; | ||
193 | th.outrate = tnext.outrate = 0; | ||
194 | } | ||
195 | |||
196 | gdImageLine (graph, xtr (start - th.time), ytr (th.outrate), | ||
197 | xtr (start - tnext.time), ytr (tnext.outrate), gdBrushed); | ||
170 | } | 198 | } |
171 | 199 | ||
172 | /* Border */ | 200 | /* Border */ |
173 | gdImageRectangle (graph, | 201 | gdImageRectangle (graph, |
174 | xtr (0), ytr (0), | 202 | xtr (0), ytr (0), |
175 | xtr (xmax), ytr (ymax), i_grid); | 203 | xtr (xmax), ytr (ymax), i_grid); |
176 | 204 | ||
177 | 205 | ||
178 | dotted_style[0] = i_grid; | 206 | dotted_style[0] = i_grid; |
179 | dotted_style[1] = gdTransparent; | 207 | dotted_style[1] = gdTransparent; |
diff --git a/src/output.c b/src/output.c index e376ad4..4b6e206 100644 --- a/src/output.c +++ b/src/output.c | |||
@@ -41,6 +41,7 @@ scale_sample (struct monitor *mon, | |||
41 | out->inrate = in->inrate; | 41 | out->inrate = in->inrate; |
42 | out->outrate = in->outrate; | 42 | out->outrate = in->outrate; |
43 | } | 43 | } |
44 | out->time = in->time; | ||
44 | out->inrate *= mon->scale; | 45 | out->inrate *= mon->scale; |
45 | out->outrate *= mon->scale; | 46 | out->outrate *= mon->scale; |
46 | } | 47 | } |
@@ -230,7 +231,7 @@ format_timestamp (FILE *fp, union value v, const char *fmt, int prec) | |||
230 | if (!fmt) | 231 | if (!fmt) |
231 | fmt = "%c"; | 232 | fmt = "%c"; |
232 | 233 | ||
233 | fprintftime(fp, fmt, tm, 0, 0); | 234 | fprintftime (fp, fmt, tm, 0, 0); |
234 | } | 235 | } |
235 | 236 | ||
236 | int | 237 | int |
diff --git a/src/readconfig.c b/src/readconfig.c index 9eff4c7..e75cae4 100644 --- a/src/readconfig.c +++ b/src/readconfig.c | |||
@@ -89,10 +89,12 @@ cb_monitor (enum grecs_callback_command cmd, | |||
89 | switch (cmd) | 89 | switch (cmd) |
90 | { | 90 | { |
91 | case grecs_callback_section_begin: | 91 | case grecs_callback_section_begin: |
92 | if (!value || value->type != GCONF_TYPE_STRING) | 92 | if (!value |
93 | || value->type != GCONF_TYPE_STRING | ||
94 | || value->v.string == NULL) | ||
93 | { | 95 | { |
94 | grecs_error (locus, 0, _("tag must be a string")); | 96 | grecs_error (locus, 0, _("tag must be a string")); |
95 | return 0; | 97 | return 1; |
96 | } | 98 | } |
97 | mon = xzalloc (sizeof (*mon)); | 99 | mon = xzalloc (sizeof (*mon)); |
98 | mon->id = strdup (value->v.string); | 100 | mon->id = strdup (value->v.string); |
@@ -399,10 +401,11 @@ cb_server (enum grecs_callback_command cmd, | |||
399 | switch (cmd) | 401 | switch (cmd) |
400 | { | 402 | { |
401 | case grecs_callback_section_begin: | 403 | case grecs_callback_section_begin: |
402 | if (!value || value->type != GCONF_TYPE_STRING) | 404 | if (!value || value->type != GCONF_TYPE_STRING |
405 | || !value->v.string) | ||
403 | { | 406 | { |
404 | grecs_error (locus, 0, _("tag must be a string")); | 407 | grecs_error (locus, 0, _("tag must be a string")); |
405 | return 0; | 408 | return 1; |
406 | } | 409 | } |
407 | cfg = xzalloc (sizeof (*cfg)); | 410 | cfg = xzalloc (sizeof (*cfg)); |
408 | cfg->id = value->v.string; | 411 | cfg->id = value->v.string; |
@@ -482,6 +485,9 @@ static struct grecs_keyword tagr_kw[] = { | |||
482 | { "zero-unknown", NULL, | 485 | { "zero-unknown", NULL, |
483 | N_("Zero-out missing samples (not implemented)") /* FIXME */, | 486 | N_("Zero-out missing samples (not implemented)") /* FIXME */, |
484 | grecs_type_bool, &zero_unknown_option }, | 487 | grecs_type_bool, &zero_unknown_option }, |
488 | { "cut-out-fraction", N_("arg: double"), NULL, /* FIXME */ | ||
489 | grecs_type_string, &cut_out_fraction, 0, | ||
490 | cb_double }, | ||
485 | { "fill-incoming", NULL, N_("Fill incoming graph"), | 491 | { "fill-incoming", NULL, N_("Fill incoming graph"), |
486 | grecs_type_bool, &fill_incoming_option }, | 492 | grecs_type_bool, &fill_incoming_option }, |
487 | 493 | ||
@@ -547,6 +553,8 @@ readconfig () | |||
547 | rc = grecs_parse (configfile); | 553 | rc = grecs_parse (configfile); |
548 | if (rc == 0) | 554 | if (rc == 0) |
549 | mon_base = obstack_finish (&mon_stack); | 555 | mon_base = obstack_finish (&mon_stack); |
556 | if (cut_out_fraction < 1.0) | ||
557 | cut_out_fraction = TAGR_CUT_OUT; | ||
550 | return rc; | 558 | return rc; |
551 | } | 559 | } |
552 | 560 | ||
diff --git a/src/report.c b/src/report.c index 398881b..71a735f 100644 --- a/src/report.c +++ b/src/report.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <arpa/inet.h> | 30 | #include <arpa/inet.h> |
31 | #include <tagr.h> | 31 | #include <tagr.h> |
32 | #include <report.h> | 32 | #include <report.h> |
33 | #include <fprintftime.h> | ||
33 | #include <gdbm.h> | 34 | #include <gdbm.h> |
34 | 35 | ||
35 | static char *dbname; | 36 | static char *dbname; |
@@ -144,6 +145,14 @@ write_db (struct monitor *mon, struct traffic_record *tr) | |||
144 | } | 145 | } |
145 | 146 | ||
146 | static void | 147 | static void |
148 | print_time (FILE *fp, time_t time) | ||
149 | { | ||
150 | fprintf (fp, "%lu [", (unsigned long) time); | ||
151 | fprintftime (fp, "%Y-%m-%d %H:%M:%S %z", localtime (&time), 0, 0); | ||
152 | fprintf (fp, "]"); | ||
153 | } | ||
154 | |||
155 | static void | ||
147 | print_queue (const char *title, queue_t *q) | 156 | print_queue (const char *title, queue_t *q) |
148 | { | 157 | { |
149 | int i, count; | 158 | int i, count; |
@@ -155,7 +164,9 @@ print_queue (const char *title, queue_t *q) | |||
155 | for (i = count - 1; i >= 0; i--) | 164 | for (i = count - 1; i >= 0; i--) |
156 | { | 165 | { |
157 | struct traffic_history *th = queue_get_ptr (q, i); | 166 | struct traffic_history *th = queue_get_ptr (q, i); |