diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-26 00:52:15 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-26 00:52:15 +0300 |
commit | 099a946ad4465c42db4737b247f1e89bd03c83ae (patch) | |
tree | af302f68f078305d27eeea1716405f79aac81877 /src | |
parent | d039b6b354119ff8735e4992dbf06760ea28fa55 (diff) | |
download | tagr-099a946ad4465c42db4737b247f1e89bd03c83ae.tar.gz tagr-099a946ad4465c42db4737b247f1e89bd03c83ae.tar.bz2 |
Improve graphical presentation. Other bugfixes.
* src/graph.c (draw_graph): Cut off values of Y greater than YMAX
Use scale_sample to prepare data.
* src/grid.c (ygrid_create): New function.
(ygrid_next): Use data prepared by ygrid_create.
* src/main.c (change_user): Bugfix.
Update calls to open_db
Move log initialization to the proper place.
* src/output.c (scale_sample): New function.
(add_stats): Use scale_sample to prepare data.
(cb_monitor): Initialize scale and ystep.
(cb_double): New function.
(monitor_kw): New keywords: scale, y-step and swap.
* src/report.c (open_db): Take an argument specifying whether
the database will be written to. All callers updated.
* src/tagr.h (struct monitor): New members: scale, ystep and swap.
max_rate is ulong.
(TAGR_DB_RD, TAGR_DB_WR): New macros.
(open_db): Update proto.
(scale_sample): New proto.
Diffstat (limited to 'src')
-rw-r--r-- | src/graph.c | 26 | ||||
-rw-r--r-- | src/grid.c | 21 | ||||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/output.c | 48 | ||||
-rw-r--r-- | src/readconfig.c | 48 | ||||
-rw-r--r-- | src/report.c | 10 | ||||
-rw-r--r-- | src/stat.c | 4 | ||||
-rw-r--r-- | src/tagr.h | 12 |
8 files changed, 143 insertions, 46 deletions
diff --git a/src/graph.c b/src/graph.c index 0d9f9a7..16483bb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -98,7 +98,7 @@ draw_graph (FILE *fp, xscale = (double) graph_xsize / xmax; #define ytr(y) \ - (unsigned long) ((ymax - (y)) * yscale + graph_h_margin[1]) + (unsigned long) ((ymax >= (y) ? (ymax - (y)) : ymax) * yscale + graph_h_margin[1]) #define xtr(x) \ (unsigned long) (growright ? \ ((full_xsize - (x)*xscale)) : \ @@ -146,25 +146,29 @@ draw_graph (FILE *fp, /* Incoming traffic */ for (i = n - 1, x = 0; i > 0 && x < xmax; i--, x += xstep) { - struct traffic_history *th = queue_get_ptr (dataq, i); - struct traffic_history *tnext = queue_get_ptr (dataq, i - 1); + struct traffic_history th, tnext; + + scale_sample (mon, queue_get_ptr (dataq, i), &th); + scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); if (fill_incoming_option) gdImageLine (graph, xtr (x), ytr (0), - xtr (x), ytr (tnext->inrate), i_in); - gdImageLine (graph, xtr (x), ytr (th->inrate), - xtr (x+1), ytr (tnext->inrate), i_in); + xtr (x), ytr (tnext.inrate), i_in); + gdImageLine (graph, xtr (x), ytr (th.inrate), + xtr (x+1), ytr (tnext.inrate), i_in); } /* Outgoing traffic */ gdImageSetBrush (graph, brush_out); for (i = n - 1, x = 0; i > 0 && x < xmax; i--, x += xstep) { - struct traffic_history *th = queue_get_ptr (dataq, i); - struct traffic_history *tnext = queue_get_ptr (dataq, i - 1); + struct traffic_history th, tnext; + + scale_sample (mon, queue_get_ptr (dataq, i), &th); + scale_sample (mon, queue_get_ptr (dataq, i - 1), &tnext); - gdImageLine (graph, xtr (x), ytr (th->outrate), - xtr (x+1), ytr (tnext->outrate), gdBrushed); + gdImageLine (graph, xtr (x), ytr (th.outrate), + xtr (x+1), ytr (tnext.outrate), gdBrushed); } /* Border */ @@ -178,7 +182,7 @@ draw_graph (FILE *fp, dotted_style[2] = gdTransparent; gdImageSetStyle (graph, dotted_style, 3); - grid = grid_create (ygrid, dataq, 0, ymax, NULL); + grid = grid_create (ygrid, dataq, 0, ymax, mon); if (grid) { unsigned long i; @@ -80,12 +80,27 @@ grid_free_data (void *ptr) } +struct ygrid_data +{ + unsigned long step; +}; + +static void * +ygrid_create (grid_t grid, void *cdata) +{ + struct monitor *mon = cdata; + struct ygrid_data *gr = xmalloc (sizeof (*gr)); + gr->step = mon->ystep; + return gr; +} + static unsigned long ygrid_next (grid_t grid, char **str, int *mark) { + struct ygrid_data *gr = grid->data; if (mark) *mark = 0; - grid->cur += 100; /* FIXME: where to configure? */ + grid->cur += gr->step; if (grid->cur < grid->vmax) { if (grid->str) @@ -100,9 +115,9 @@ ygrid_next (grid_t grid, char **str, int *mark) } struct grid_class grid_class_y = { - NULL, + ygrid_create, ygrid_next, - NULL + grid_free_data }; @@ -432,7 +432,7 @@ change_user () if (user == NULL) return; - if (getuid ()) + if (getuid () == 0) { logmsg (L_NOTICE, "not a superuser: ignoring the `user' statement"); return; @@ -492,7 +492,7 @@ decode_buffer () } } - open_db (); + open_db (TAGR_DB_WR); for (i = 0; i < reply->n_addr; i++, sp++) { sp->in = ntohl (sp->in); @@ -530,7 +530,7 @@ read_input (const char *name) verbose (2, "Reading `%s'", name); - open_db (); + open_db (TAGR_DB_WR); while (getline (&buf, &bufsize, fp) > 0) { char *p; @@ -758,17 +758,14 @@ main (int argc, char **argv) argp_program_version_hook = tagr_version; if (!isatty (2)) - log_to_stderr = 0; + { + log_to_stderr = 0; + } init_syslog (argv[0]); if (argp_parse (&argp, argc, argv, 0, &index, NULL)) exit (EX_USAGE); - if (log_to_stderr == -1) - log_to_stderr = foreground && isatty (0); - grecs_log_to_stderr = log_to_stderr; - init_syslog (program_invocation_short_name); - if (html_template_option) html_template = html_template_option; @@ -790,6 +787,11 @@ main (int argc, char **argv) exit (0); } + if (log_to_stderr == -1) + log_to_stderr = foreground && isatty (0); + grecs_log_to_stderr = log_to_stderr; + init_syslog (program_invocation_short_name); + if (test_template_option) { CHECK_USAGE (import_option, "--import", "--test-template"); diff --git a/src/output.c b/src/output.c index 193bdfc..980f9e1 100644 --- a/src/output.c +++ b/src/output.c @@ -25,6 +25,25 @@ #include <sys/stat.h> #include <tagr.h> +void +scale_sample (struct monitor *mon, + const struct traffic_history *in, + struct traffic_history *out) +{ + if (mon->swap) + { + out->inrate = in->outrate; + out->outrate = in->inrate; + } + else + { + out->inrate = in->inrate; + out->outrate = in->outrate; + } + out->inrate *= mon->scale; + out->outrate *= mon->scale; +} + int create_hierarchy (char *dir, int perm) { @@ -86,32 +105,35 @@ enum symname_index }; static void -add_stats (pp_tab_t **ptab, queue_t *q, const char **symname) +add_stats (pp_tab_t **ptab, struct monitor *mon, queue_t *q, + const char **symname) { double val[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; int i, n = queue_count (q); - struct traffic_history *th; + struct traffic_history *tptr, th; if (!n) return; for (i = 0; i < n; i++) { - th = queue_get_ptr (q, i); + tptr = queue_get_ptr (q, i); + scale_sample (mon, tptr, &th); - val[avgin_name] += th->inrate; - if (th->inrate > val[maxin_name]) - val[maxin_name] = th->inrate; + val[avgin_name] += th.inrate; + if (th.inrate > val[maxin_name]) + val[maxin_name] = th.inrate; - val[avgout_name] += th->outrate; - if (th->outrate > val[maxout_name]) - val[maxout_name] = th->outrate; + val[avgout_name] += th.outrate; + if (th.outrate > val[maxout_name]) + val[maxout_name] = th.outrate; } val[avgin_name] /= n; val[avgout_name] /= n; - th = queue_get_tail (q); - val[curin_name] = th->inrate; - val[curout_name] = th->outrate; + tptr = queue_get_tail (q); + scale_sample (mon, tptr, &th); + val[curin_name] = th.inrate; + val[curout_name] = th.outrate; for (i = 0; i < sizeof (val) / sizeof (val[0]); i++) add_numeric_value (ptab, symname[i], val[i]); @@ -141,7 +163,7 @@ do_update_output (struct monitor *mon, struct image_descr *dscr, { FILE *fp; - add_stats (ptab, queue, dscr->symname); + add_stats (ptab, mon, queue, dscr->symname); fp = fopen (fname, "w"); if (!fp) diff --git a/src/readconfig.c b/src/readconfig.c index 208731e..e60d335 100644 --- a/src/readconfig.c +++ b/src/readconfig.c @@ -96,6 +96,8 @@ cb_monitor (enum grecs_callback_command cmd, } mon = xzalloc (sizeof (*mon)); mon->id = strdup (value->v.string); + mon->scale = 1.0; + mon->ystep = 100; *pdata = mon; break; @@ -126,6 +128,41 @@ cb_monitor (enum grecs_callback_command cmd, return 0; } +static int +cb_double (enum grecs_callback_command cmd, + grecs_locus_t *locus, + void *varptr, + grecs_value_t *value, + void *cb_data) +{ + double d, *dptr = varptr; + char *p; + + if (cmd != grecs_callback_set_value) + { + grecs_error (locus, 0, _("unexpected block statement")); + return 1; + } + if (value->type != GCONF_TYPE_STRING) + { + grecs_error (locus, 0, _("expected scalar value but found list")); + return 1; + } + d = strtod (value->v.string, &p); + if (*p) + { + grecs_error (locus, 0, _("not a valid double precision value")); + return 1; + } + if (d < 0) + { + grecs_error (locus, 0, _("negative values not allowed")); + return 1; + } + *dptr = d; + + return 0; +} static struct grecs_keyword monitor_kw[] = { { "host", NULL, N_("Host name or IP address"), @@ -133,9 +170,16 @@ static struct grecs_keyword monitor_kw[] = { { "directory", N_("name"), N_("Subdirectory name"), grecs_type_string, NULL, offsetof(struct monitor, dir) }, { "max-speed", NULL, N_("Maximum speed"), - grecs_type_size, NULL, offsetof(struct monitor, max_rate) }, + grecs_type_ulong, NULL, offsetof(struct monitor, max_rate) }, { "rate-units", NULL, N_("Name of rate units"), grecs_type_string, NULL, offsetof(struct monitor, rate_unit) }, + { "scale", N_("arg: double"), N_("Scaling factor"), + grecs_type_string, NULL, offsetof(struct monitor, scale), + cb_double }, + { "y-step", NULL, N_("Step for Y axis"), + grecs_type_ulong, NULL, offsetof(struct monitor, ystep) }, + { "swap", NULL, N_("Swap in and out rates"), + grecs_type_bool, NULL, offsetof(struct monitor, swap) }, { NULL } }; @@ -274,7 +318,7 @@ cb_facility (enum grecs_callback_command cmd, if (cmd != grecs_callback_set_value) { - grecs_error (locus, 0, _("Unexpected block statement")); + grecs_error (locus, 0, _("unexpected block statement")); return 1; } if (value->type != GCONF_TYPE_STRING) diff --git a/src/report.c b/src/report.c index 3d32085..ed8a34d 100644 --- a/src/report.c +++ b/src/report.c @@ -42,13 +42,15 @@ tagr_db_report (char *str) } void -open_db () +open_db (int flag) { dbname = xmalloc (strlen (basedir) + 1 + sizeof (TAGR_DBNAME)); strcpy (dbname, basedir); strcat (dbname, "/"); strcat (dbname, TAGR_DBNAME); - dbf = gdbm_open (dbname, 0, GDBM_WRCREAT, TAGR_DBMODE, tagr_db_report); + dbf = gdbm_open (dbname, 0, + flag == TAGR_DB_WR ? GDBM_WRCREAT : GDBM_READER, + TAGR_DBMODE, tagr_db_report); if (dbf == NULL) { logmsg (L_ERR, "Cannot open database %s: %s", @@ -196,7 +198,7 @@ list_db () datum content; struct monitor *mon; - open_db (); + open_db (TAGR_DB_RD); key = gdbm_firstkey (dbf); while (key.dptr) { @@ -272,7 +274,7 @@ rebuild (int force) time_t now = time (NULL); verbose (1, "rebuild initiated"); - open_db (); + open_db (TAGR_DB_WR); key = gdbm_firstkey (dbf); while (key.dptr) { @@ -422,7 +422,7 @@ import (const char *dirname) die (EX_OSERR, "cannot stat file `%s': %s", dirname, strerror (errno)); else if (S_ISREG (st.st_mode)) { - open_db (); + open_db (TAGR_DB_WR); if (import_log (dirname) == 0) count++; close_db (); @@ -441,7 +441,7 @@ import (const char *dirname) switch (rc) { case 0: - open_db (); + open_db (TAGR_DB_WR); for (i = 0; i < gl.gl_pathc; i++) if (import_log (gl.gl_pathv[i]) == 0) count++; @@ -36,7 +36,10 @@ struct monitor char *name; char *dir; char *rate_unit; - unsigned max_rate; + unsigned long max_rate; + double scale; + unsigned long ystep; + int swap; }; extern struct grecs_sockaddr listen_sockaddr; @@ -201,7 +204,9 @@ struct traffic_record /* report.c */ -void open_db (); +#define TAGR_DB_RD 0 +#define TAGR_DB_WR 1 +void open_db (int); void close_db (); void read_db (struct monitor *mon, struct traffic_record **tr); void write_db (struct monitor *mon, struct traffic_record *tr); @@ -226,6 +231,9 @@ char *mkfilename (const char *dir, const char *name, const char *suffix); /* output.c */ +void scale_sample (struct monitor *mon, + const struct traffic_history *in, + struct traffic_history *out); int update_output (struct monitor *mon, struct traffic_record *tr, time_t timestamp, int force); |