src/rrd_{fetch,graph}.c: Implement `--daemon'.
authorFlorian Forster <octo@leeloo.home.verplant.org>
Tue, 24 Jun 2008 18:50:51 +0000 (20:50 +0200)
committerFlorian Forster <octo@leeloo.home.verplant.org>
Tue, 24 Jun 2008 18:50:51 +0000 (20:50 +0200)
Both commands not accept the `--daemon' option. When specified, a `flush'
command is send to the daemon just before reading the RRD file, so that
the output will contain the newest data available - even with (very) long
cache timeouts.

doc/rrdfetch.pod
doc/rrdgraph.pod
src/rrd.h
src/rrd_fetch.c
src/rrd_graph.c
src/rrd_graph.h
src/rrd_tool.c
src/rrd_tool.h

index 51b5ccd..62736fa 100644 (file)
@@ -48,6 +48,17 @@ the end of the time series in seconds since epoch. See also AT-STYLE
 TIME SPECIFICATION section for a detailed explanation of how to
 specify the end time.
 
+=item B<--daemon> I<address>
+
+Address of the L<rrdcached(1)> daemon. If specified, a C<flush> command is sent
+to the server before reading the RRD files. This allows B<rrdtool> to return
+fresh data even if the daemon is configured to cache values for a long time. To
+specify a UNIX domain socket use the prefix C<unix:>, see example below. Other
+addresses are interpreted as normal network addresses, i.E<nbsp>e. IPv4 or IPv6
+addresses in most cases.
+
+ rrdtool fetch --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd AVERAGE
+
 =back
 
 =head2 RESOLUTION INTERVAL
index 048171a..592cb9b 100644 (file)
@@ -248,7 +248,7 @@ to the more robust B<--alt-y-grid> mode.
 
 How many digits should rrdtool assume the y-axis labels to be? You
 may have to use this option to make enough space once you start
-fideling with the y-axis labeling.
+fiddling with the y-axis labeling.
 
 [B<--units=si>]
 
@@ -265,6 +265,17 @@ Note that for linear graphs, SI notation is used by default.
 Only generate the graph if the current graph is out of date or not
 existent.
 
+[B<--daemon> I<address>]
+
+Address of the L<rrdcached(1)> daemon. If specified, a C<flush> command is sent
+to the server before reading the RRD files. This allows the graph to contain
+fresh data even if the daemon is configured to cache values for a long time. To
+specify a UNIX domain socket use the prefix C<unix:>, see example below. Other
+addresses are interpreted as normal network addresses, i.E<nbsp>e. IPv4 or IPv6
+addresses in most cases.
+
+ rrdtool fetch --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd AVERAGE
+
 [B<-f>|B<--imginfo> I<printfstr>]
 
 After the image has been created, the graph function uses printf
index 31fd468..daed0e2 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -217,15 +217,16 @@ extern    "C" {
     const char *_template,
     int argc,
     const char **argv);
-    int       rrd_fetch_r(
-    const char *filename,
-    const char *cf,
-    time_t *start,
-    time_t *end,
-    unsigned long *step,
-    unsigned long *ds_cnt,
-    char ***ds_namv,
-    rrd_value_t **data);
+    int rrd_fetch_r (
+            const char *filename,
+            const char *cf,
+            time_t *start,
+            time_t *end,
+            unsigned long *step,
+            const char *daemon,
+            unsigned long *ds_cnt,
+            char ***ds_namv,
+            rrd_value_t **data);
     int       rrd_dump_r(
     const char *filename,
     char *outname);
index 4ea2eb1..c745f06 100644 (file)
@@ -53,6 +53,7 @@
  *****************************************************************************/
 
 #include "rrd_tool.h"
+#include "rrd_client.h"
 
 #include "rrd_is_thread_safe.h"
 /*#define DEBUG*/
@@ -72,6 +73,7 @@ int rrd_fetch(
     long      step_tmp = 1;
     time_t    start_tmp = 0, end_tmp = 0;
     const char *cf;
+    char *daemon = NULL;
 
     rrd_time_value_t start_tv, end_tv;
     char     *parsetime_error = NULL;
@@ -79,6 +81,7 @@ int rrd_fetch(
         {"resolution", required_argument, 0, 'r'},
         {"start", required_argument, 0, 's'},
         {"end", required_argument, 0, 'e'},
+        {"daemon", required_argument, 0, 'd'},
         {0, 0, 0, 0}
     };
 
@@ -93,7 +96,7 @@ int rrd_fetch(
         int       option_index = 0;
         int       opt;
 
-        opt = getopt_long(argc, argv, "r:s:e:", long_options, &option_index);
+        opt = getopt_long(argc, argv, "r:s:e:d:", long_options, &option_index);
 
         if (opt == EOF)
             break;
@@ -114,6 +117,18 @@ int rrd_fetch(
         case 'r':
             step_tmp = atol(optarg);
             break;
+
+        case 'd':
+           if (daemon != NULL)
+                   free (daemon);
+            daemon = strdup (optarg);
+            if (daemon == NULL)
+            {
+                rrd_set_error ("strdup failed.");
+                return (-1);
+            }
+            break;
+
         case '?':
             rrd_set_error("unknown option '-%c'", optopt);
             return (-1);
@@ -153,8 +168,8 @@ int rrd_fetch(
 
     cf = argv[optind + 1];
 
-    if (rrd_fetch_r(argv[optind], cf, start, end, step, ds_cnt, ds_namv, data)
-        != 0)
+    if (rrd_fetch_r(argv[optind], cf, start, end, step, daemon, ds_cnt,
+                           ds_namv, data) != 0)
         return (-1);
     return (0);
 }
@@ -167,19 +182,36 @@ int rrd_fetch_r(
                          * will be changed to represent reality */
     unsigned long *step,    /* which stepsize do you want? 
                              * will be changed to represent reality */
+    const char *daemon,
     unsigned long *ds_cnt,  /* number of data sources in file */
     char ***ds_namv,    /* names of data_sources */
     rrd_value_t **data)
 {                       /* two dimensional array containing the data */
     enum cf_en cf_idx;
+    int status;
 
     if ((int) (cf_idx = cf_conv(cf)) == -1) {
         return -1;
     }
 
-    return (rrd_fetch_fn
-            (filename, cf_idx, start, end, step, ds_cnt, ds_namv, data));
-}
+    if (daemon != NULL)
+    {
+        status = rrdc_connect (daemon);
+        if (status != 0)
+        {
+            rrd_set_error ("rrdc_connect failed with status %i.", status);
+            return (-1);
+        }
+    }
+
+    status = rrd_fetch_fn (filename, cf_idx, start, end, step,
+            (daemon == NULL) ? 0 : 1,
+            ds_cnt, ds_namv, data);
+
+    rrdc_disconnect ();
+
+    return (status);
+} /* int rrd_fetch_r */
 
 int rrd_fetch_fn(
     const char *filename,   /* name of the rrd */
@@ -189,6 +221,7 @@ int rrd_fetch_fn(
                          * will be changed to represent reality */
     unsigned long *step,    /* which stepsize do you want? 
                              * will be changed to represent reality */
+    int use_rrdcached,
     unsigned long *ds_cnt,  /* number of data sources in file */
     char ***ds_namv,    /* names of data_sources */
     rrd_value_t **data)
@@ -208,6 +241,18 @@ int rrd_fetch_fn(
     rrd_value_t *data_ptr;
     unsigned long rows;
 
+    if (use_rrdcached)
+    {
+        int status;
+
+        status = rrdc_flush (filename);
+        if (status != 0)
+        {
+            rrd_set_error ("rrdc_flush failed with status %i.", status);
+            return (-1);
+        }
+    }
+
 #ifdef DEBUG
     fprintf(stderr, "Entered rrd_fetch_fn() searching for the best match\n");
     fprintf(stderr, "Looking for: start %10lu end %10lu step %5lu\n",
index 300fdbe..1e597d1 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include "rrd_graph.h"
+#include "rrd_client.h"
 
 /* some constant definitions */
 
@@ -302,6 +303,13 @@ int im_free(
 
     if (im == NULL)
         return 0;
+
+    if (im->use_rrdcached)
+    {
+        rrdc_disconnect ();
+        im->use_rrdcached = 0;
+    }
+
     for (i = 0; i < (unsigned) im->gdes_c; i++) {
         if (im->gdes[i].data_first) {
             /* careful here, because a single pointer can occur several times */
@@ -829,6 +837,7 @@ int data_fetch(
                               &im->gdes[i].start,
                               &im->gdes[i].end,
                               &ft_step,
+                              im->use_rrdcached ? 1 : 0,
                               &im->gdes[i].ds_cnt,
                               &im->gdes[i].ds_namv,
                               &im->gdes[i].data)) == -1) {
@@ -3709,6 +3718,7 @@ void rrd_graph_init(
     im->grinfo_current = (rrd_info_t *) NULL;
     im->imgformat = IF_PNG;
     im->imginfo = NULL;
+    im->use_rrdcached = 0;
     im->lazy = 0;
     im->logarithmic = 0;
     im->maxval = DNAN;
@@ -3827,6 +3837,7 @@ void rrd_graph_options(
         { "watermark",          required_argument, 0, 'W'},
         { "alt-y-mrtg",         no_argument,       0, 1000},    /* this has no effect it is just here to save old apps from crashing when they use it */
         { "pango-markup",       no_argument,       0, 'P'},
+        { "daemon",             required_argument, 0, 'd'},
         {  0, 0, 0, 0}
 };
 /* *INDENT-ON* */
@@ -3841,7 +3852,7 @@ void rrd_graph_options(
         int       col_start, col_end;
 
         opt = getopt_long(argc, argv,
-                          "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kP",
+                          "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kPd:",
                           long_options, &option_index);
         if (opt == EOF)
             break;
@@ -4185,6 +4196,25 @@ void rrd_graph_options(
             strncpy(im->watermark, optarg, 100);
             im->watermark[99] = '\0';
             break;
+        case 'd':
+        {
+            int status;
+            if (im->use_rrdcached)
+            {
+                rrd_set_error ("You cannot specify --daemon "
+                        "more than once.");
+                return;
+            }
+            status = rrdc_connect (optarg);
+            if (status != 0)
+            {
+                rrd_set_error ("rrdc_connect(%s) failed with status %i.",
+                        optarg, status);
+                return;
+            }
+            im->use_rrdcached = 1;
+            break;
+        }
         case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
index 2b1c05b..c21f356 100644 (file)
@@ -210,6 +210,7 @@ typedef struct image_desc_t {
     char     *imginfo;  /* construct an <IMG ... tag and return 
                            as first retval */
     enum gfx_if_en imgformat;   /* image format */
+    int       use_rrdcached;
     int       lazy;     /* only update the image if there is
                            reasonable probablility that the
                            existing one is out of date */
index 8efd492..b5a2df9 100644 (file)
@@ -113,7 +113,8 @@ void PrintUsage(
         N_("* fetch - fetch data out of an RRD\n\n"
            "\trrdtool fetch filename.rrd CF\n"
            "\t\t[-r|--resolution resolution]\n"
-           "\t\t[-s|--start start] [-e|--end end]\n\n");
+           "\t\t[-s|--start start] [-e|--end end]\n"
+          "\t\t[--daemon <address>]\n\n");
 
 /* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
 
@@ -132,7 +133,7 @@ void PrintUsage(
            "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
            "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
            "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
-           "\t\t[-g|--no-legend]\n"
+           "\t\t[-g|--no-legend] [--daemon <address>]\n"
            "\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
     const char *help_graph2 =
         N_("\t\t[-n|--font FONTTAG:size:font]\n"
index 0be66e4..63359b6 100644 (file)
@@ -77,15 +77,15 @@ extern    "C" {
     int       rrd_create_fn(
     const char *file_name,
     rrd_t *rrd);
-    int       rrd_fetch_fn(
-    const char *filename,
-    enum cf_en cf_idx,
-    time_t *start,
-    time_t *end,
-    unsigned long *step,
-    unsigned long *ds_cnt,
-    char ***ds_namv,
-    rrd_value_t **data);
+    int rrd_fetch_fn (const char *filename,
+            enum cf_en cf_idx,
+            time_t *start,
+            time_t *end,
+            unsigned long *step,
+            int use_rrdcached,
+            unsigned long *ds_cnt,
+            char ***ds_namv,
+            rrd_value_t **data);
 
 #define RRD_READONLY    (1<<0)
 #define RRD_READWRITE   (1<<1)