[rrd-developers] [PATCH] src/rrd_graph.[ch]: Implemented the ":daemon=..." option for "DEF:" commands.

Thorsten von Eicken tve at voneicken.com
Wed Feb 24 22:02:57 CET 2010


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<octo at 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;
>    



More information about the rrd-developers mailing list