aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@Pirx.gnu.org.ua>2009-04-28 16:27:03 +0300
committerSergey Poznyakoff <gray@Pirx.gnu.org.ua>2009-04-28 16:27:03 +0300
commit20d7f1d7e051c6b021a3f5d088985a74c3370b29 (patch)
tree5c5dc1c1b401e055096b8ec216a6bd97eb76a520
parent29e4b3da0990aca9db232dc3ce0a57722ccf1cac (diff)
downloadtagr-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--TODO5
-rw-r--r--src/graph.c46
-rw-r--r--src/output.c3
-rw-r--r--src/readconfig.c16
-rw-r--r--src/report.c23
-rw-r--r--src/stat.c64
-rw-r--r--src/tagr.h8
7 files changed, 113 insertions, 52 deletions
diff --git a/TODO b/TODO
index 9a8e27f..b2edd7c 100644
--- a/TODO
+++ b/TODO
@@ -9,9 +9,10 @@ S: +OK accepted
9C: QUIT 9C: QUIT
10S: +OK bye 10S: +OK bye
11 11
12* Zero-unknown option and interrupted data feeds 12* Drawing interrupted data feeds
13 13
14Decide what to do if a data feed gets interrupted. 14What to do if zero-inknown is set to `false'? Currently, linear
15interpolation 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
236int 237int
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
35static char *dbname; 36static char *dbname;
@@ -144,6 +145,14 @@ write_db (struct monitor *mon, struct traffic_record *tr)
144} 145}
145 146
146static void 147static void
148print_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
155static void
147print_queue (const char *title, queue_t *q) 156print_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);