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.
 
 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
 =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
 
 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>]
 
 
 [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.
 
 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
 [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);
     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);
     int       rrd_dump_r(
     const char *filename,
     char *outname);
index 4ea2eb1..c745f06 100644 (file)
@@ -53,6 +53,7 @@
  *****************************************************************************/
 
 #include "rrd_tool.h"
  *****************************************************************************/
 
 #include "rrd_tool.h"
+#include "rrd_client.h"
 
 #include "rrd_is_thread_safe.h"
 /*#define DEBUG*/
 
 #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;
     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;
 
     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'},
         {"resolution", required_argument, 0, 'r'},
         {"start", required_argument, 0, 's'},
         {"end", required_argument, 0, 'e'},
+        {"daemon", required_argument, 0, 'd'},
         {0, 0, 0, 0}
     };
 
         {0, 0, 0, 0}
     };
 
@@ -93,7 +96,7 @@ int rrd_fetch(
         int       option_index = 0;
         int       opt;
 
         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;
 
         if (opt == EOF)
             break;
@@ -114,6 +117,18 @@ int rrd_fetch(
         case 'r':
             step_tmp = atol(optarg);
             break;
         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);
         case '?':
             rrd_set_error("unknown option '-%c'", optopt);
             return (-1);
@@ -153,8 +168,8 @@ int rrd_fetch(
 
     cf = argv[optind + 1];
 
 
     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);
 }
         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 */
                          * 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;
     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;
     }
 
 
     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 */
 
 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 */
                          * 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)
     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;
 
     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",
 #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"
 #endif
 
 #include "rrd_graph.h"
+#include "rrd_client.h"
 
 /* some constant definitions */
 
 
 /* some constant definitions */
 
@@ -302,6 +303,13 @@ int im_free(
 
     if (im == NULL)
         return 0;
 
     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 */
     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->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) {
                               &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->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;
     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'},
         { "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* */
         {  0, 0, 0, 0}
 };
 /* *INDENT-ON* */
@@ -3841,7 +3852,7 @@ void rrd_graph_options(
         int       col_start, col_end;
 
         opt = getopt_long(argc, argv,
         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;
                           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;
             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);
         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 */
     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 */
     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"
         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*/
 
 
 /* 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[-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"
            "\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_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)
 
 #define RRD_READONLY    (1<<0)
 #define RRD_READWRITE   (1<<1)