aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-04-26 00:52:15 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-04-26 00:52:15 +0300
commit099a946ad4465c42db4737b247f1e89bd03c83ae (patch)
treeaf302f68f078305d27eeea1716405f79aac81877 /src
parentd039b6b354119ff8735e4992dbf06760ea28fa55 (diff)
downloadtagr-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.c26
-rw-r--r--src/grid.c21
-rw-r--r--src/main.c20
-rw-r--r--src/output.c48
-rw-r--r--src/readconfig.c48
-rw-r--r--src/report.c10
-rw-r--r--src/stat.c4
-rw-r--r--src/tagr.h12
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;
diff --git a/src/grid.c b/src/grid.c
index 3c01ce4..f4a75e1 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -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
};
diff --git a/src/main.c b/src/main.c
index 9d9340c..2a20ba9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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)
{
diff --git a/src/stat.c b/src/stat.c
index 3b8fb96..ed4ab8e 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -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++;
diff --git a/src/tagr.h b/src/tagr.h
index 331e44a..b65b8d4 100644
--- a/src/tagr.h
+++ b/src/tagr.h
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.