Very cool! So now the main missing piece is the creation of RRD files, correct? Thorsten
On 2/24/2010 9:42 AM, Florian Forster wrote: > From: Florian Forster<o...@noris.net> > > Rather than calling "FLUSH" for each RRD file needed for drawing a > graph and then accessing the file directly, use the "FLUSH" command to > receive the data required for drawing a graph. > > The daemon can now be specified in one of three ways: > > * A new option has been added to the "DEF" option. If the "DEF" command > includes the option "daemon=...", then the given daemon is used for > accessing that file only. This option takes precedence over all > other options. The value given follows the same syntax as other ways > to specify a daemon address, thouh colons need to be escaped from > rrdgraph(1). > > Example: > 'DEF:v1=path/to/example.rrd:value:AVERAGE:daemon=collect1.octo.cx' > > * The "--daemon" option can be given to the overall "rrdtool graph" > command. When given, this address is used for all file accesses > except those which explicitely contain a "daemon=..." option. > > * If the "RRDCACHED_ADDRESS" environment variable is set, it's value > is used as the daemon address. This is the lowest priority option > and only used if no other option is given. > > One nice detail is that with ":daemon=...", the cache address can be > specified for each "DEF:" definition. It is therefore possible to graph > values stored on several servers in one graph – even if several RRD > files have the same name. > --- > doc/rrdgraph_data.pod | 12 ++++++- > src/rrd_graph.c | 82 > +++++++++++++++++++++++------------------------ > src/rrd_graph.h | 1 + > src/rrd_graph_helper.c | 5 +++ > 4 files changed, 56 insertions(+), 44 deletions(-) > > diff --git a/doc/rrdgraph_data.pod b/doc/rrdgraph_data.pod > index d5ceddb..57b9d0a 100644 > --- a/doc/rrdgraph_data.pod > +++ b/doc/rrdgraph_data.pod > @@ -4,7 +4,7 @@ rrdgraph_data - preparing data for graphing in rrdtool graph > > =head1 SYNOPSIS > > -B<DEF:>I<E<lt>vnameE<gt>>=I<E<lt>rrdfileE<gt>>:I<E<lt>ds-nameE<gt>>:I<E<lt>CFE<gt>>[:step=I<E<lt>stepE<gt>>][:start=I<E<lt>timeE<gt>>][:end=I<E<lt>timeE<gt>>][:reduce=I<E<lt>B<CF>E<gt>>] > +B<DEF:>I<E<lt>vnameE<gt>>=I<E<lt>rrdfileE<gt>>:I<E<lt>ds-nameE<gt>>:I<E<lt>CFE<gt>>[:step=I<E<lt>stepE<gt>>][:start=I<E<lt>timeE<gt>>][:end=I<E<lt>timeE<gt>>][:reduce=I<E<lt>B<CF>E<gt>>][:daemon=I<E<lt>addressE<gt>>] > > B<VDEF>:I<vname>=I<RPN expression> > > @@ -28,7 +28,7 @@ mixed case names for variables since operators will always > be in uppercase. > > =head1 DEF > > -B<DEF:>I<E<lt>vnameE<gt>>=I<E<lt>rrdfileE<gt>>:I<E<lt>ds-nameE<gt>>:I<E<lt>CFE<gt>>[:step=I<E<lt>stepE<gt>>][:start=I<E<lt>timeE<gt>>][:end=I<E<lt>timeE<gt>>][:reduce=I<E<lt>B<CF>E<gt>>] > +B<DEF:>I<E<lt>vnameE<gt>>=I<E<lt>rrdfileE<gt>>:I<E<lt>ds-nameE<gt>>:I<E<lt>CFE<gt>>[:step=I<E<lt>stepE<gt>>][:start=I<E<lt>timeE<gt>>][:end=I<E<lt>timeE<gt>>][:reduce=I<E<lt>B<CF>E<gt>>][:daemon=I<E<lt>addressE<gt>>] > > This command fetches data from an B<RRD> file. The virtual name > I<vname> can then be used throughout the rest of the script. By > @@ -54,12 +54,20 @@ B<DEF> itself will be used to reduce the data density. > This behavior can > be changed using C<:reduce=I<E<lt>B<CF>E<gt>>>. This optional parameter > specifies the B<CF> to use during the data reduction phase. > > +It is possible to request single data sources from a specific I<RRDCacheD>, > see > +L<rrdcached(1)>, using the C<:daemon=I<E<lt>addressE<gt>>> parameter. The > +value given to this parameter follows the same syntax as other means to > specify > +the address of the caching daemon. It is described in detail in the > +L<rrdcached(1)> manual page. Beware, however, that colons (in IPv6 addresses > +and as a port separator, for example) need to be escaped using a backslash. > + > Example: > > DEF:ds0=router.rrd:ds0:AVERAGE > DEF:ds0weekly=router.rrd:ds0:AVERAGE:step=7200 > DEF:ds0weekly=router.rrd:ds0:AVERAGE:start=end-1h > DEF:ds0weekly=router.rrd:ds0:AVERAGE:start=11\:00:end=start+1h > + DEF:ds0weekly=router.rrd:ds0:AVERAGE:daemon=collect1.example.com > > =head1 VDEF > > diff --git a/src/rrd_graph.c b/src/rrd_graph.c > index 9e23a4a..872dd44 100644 > --- a/src/rrd_graph.c > +++ b/src/rrd_graph.c > @@ -845,46 +845,48 @@ int data_fetch( > } > if (!skip) { > unsigned long ft_step = im->gdes[i].step; /* ft_step will > record what we got from fetch */ > + const char *daemon; > + int status; > > - /* Flush the file if > - * - a connection to the daemon has been established > - * - this is the first occurrence of that RRD file > - */ > - if (rrdc_is_connected(im->daemon_addr)) > + if (im->gdes[i].daemon[0] != 0) > + daemon = im->gdes[i].daemon; > + else > + daemon = im->daemon_addr; > + > + /* "daemon" may be NULL. ENV_RRDCACHED_ADDRESS is evaluated in > that > + * case. If "daemon" holds the same value as in the previous > + * iteration, no actual new connection is established - the > + * existing connection is re-used. */ > + rrdc_connect (daemon); > + > + /* If connecting was successfull, use the daemon to query the > data. > + * If there is no connection, for example because no daemon > address > + * was specified, (try to) use the local file directly. */ > + if (rrdc_is_connected (daemon)) > { > - int status; > - > - status = 0; > - for (ii = 0; ii< i; ii++) > - { > - if (strcmp (im->gdes[i].rrd, im->gdes[ii].rrd) == 0) > - { > - status = 1; > - break; > - } > - } > - > - if (status == 0) > - { > - status = rrdc_flush (im->gdes[i].rrd); > - if (status != 0) > - { > - rrd_set_error ("rrdc_flush (%s) failed with status > %i.", > - im->gdes[i].rrd, status); > - return (-1); > - } > + status = rrdc_fetch (im->gdes[i].rrd, > + cf_to_string (im->gdes[i].cf), > +&im->gdes[i].start, > +&im->gdes[i].end, > +&ft_step, > +&im->gdes[i].ds_cnt, > +&im->gdes[i].ds_namv, > +&im->gdes[i].data); > + if (status != 0) > + return (status); > + } > + else > + { > + if ((rrd_fetch_fn(im->gdes[i].rrd, > + im->gdes[i].cf, > +&im->gdes[i].start, > +&im->gdes[i].end, > +&ft_step, > +&im->gdes[i].ds_cnt, > +&im->gdes[i].ds_namv, > +&im->gdes[i].data)) == -1) { > + return -1; > } > - } /* if (rrdc_is_connected()) */ > - > - if ((rrd_fetch_fn(im->gdes[i].rrd, > - im->gdes[i].cf, > -&im->gdes[i].start, > -&im->gdes[i].end, > -&ft_step, > -&im->gdes[i].ds_cnt, > -&im->gdes[i].ds_namv, > -&im->gdes[i].data)) == -1) { > - return -1; > } > im->gdes[i].data_first = 1; > > @@ -3799,6 +3801,7 @@ int gdes_alloc( > im->gdes[im->gdes_c - 1].cf = CF_AVERAGE; > im->gdes[im->gdes_c - 1].yrule = DNAN; > im->gdes[im->gdes_c - 1].xrule = 0; > + im->gdes[im->gdes_c - 1].daemon[0] = 0; > return 0; > } > > @@ -4636,11 +4639,6 @@ void rrd_graph_options( > } > } /* while (1) */ > > - { /* try to connect to rrdcached */ > - int status = rrdc_connect(im->daemon_addr); > - if (status != 0) return; > - } > - > > pango_cairo_context_set_font_options(pango_layout_get_context(im->layout), > im->font_options); > pango_layout_context_changed(im->layout); > > diff --git a/src/rrd_graph.h b/src/rrd_graph.h > index 8e28f63..b811926 100644 > --- a/src/rrd_graph.h > +++ b/src/rrd_graph.h > @@ -158,6 +158,7 @@ typedef struct graph_desc_t { > char rrd[1024]; /* name of the rrd_file containing data */ > char ds_nam[DS_NAM_SIZE]; /* data source name */ > long ds; /* data source number */ > + char daemon[256]; > enum cf_en cf; /* consolidation function */ > enum cf_en cf_reduce; /* consolidation function for reduce_data() */ > struct gfx_color_t col; /* graph color */ > diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c > index 88d4d9a..60ef0d0 100644 > --- a/src/rrd_graph_helper.c > +++ b/src/rrd_graph_helper.c > @@ -962,6 +962,11 @@ int rrd_parse_def( > return 1; > } > dprintf("- done parsing: '%s'\n",&line[*eaten]); > + } else if (!strcmp("daemon", command)) { > + i = scan_for_col(&line[*eaten], > + sizeof (gdp->daemon), gdp->daemon); > + (*eaten) += i; > + dprintf("- using daemon '%s'\n", gdp->daemon); > } else { > rrd_set_error("Parse error in '%s'", line); > return 1; > _______________________________________________ rrd-developers mailing list rrd-developers@lists.oetiker.ch https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers