From 6d19d9d651c2b710f26ba98417f280d1b6cd9cf4 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 24 Jun 2008 20:50:51 +0200 Subject: [PATCH] src/rrd_{fetch,graph}.c: Implement `--daemon'. 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 | 11 +++++++++++ doc/rrdgraph.pod | 13 ++++++++++++- src/rrd.h | 19 ++++++++++--------- src/rrd_fetch.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/rrd_graph.c | 32 ++++++++++++++++++++++++++++++- src/rrd_graph.h | 1 + src/rrd_tool.c | 5 +++-- src/rrd_tool.h | 18 +++++++++--------- 8 files changed, 128 insertions(+), 28 deletions(-) diff --git a/doc/rrdfetch.pod b/doc/rrdfetch.pod index 51b5ccd..62736fa 100644 --- a/doc/rrdfetch.pod +++ b/doc/rrdfetch.pod @@ -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 of the L daemon. If specified, a C command is sent +to the server before reading the RRD files. This allows B 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, see example below. Other +addresses are interpreted as normal network addresses, i.Ee. 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 diff --git a/doc/rrdgraph.pod b/doc/rrdgraph.pod index 048171a..592cb9b 100644 --- a/doc/rrdgraph.pod +++ b/doc/rrdgraph.pod @@ -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 of the L daemon. If specified, a C 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, see example below. Other +addresses are interpreted as normal network addresses, i.Ee. 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] After the image has been created, the graph function uses printf diff --git a/src/rrd.h b/src/rrd.h index 31fd468..daed0e2 100644 --- 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); diff --git a/src/rrd_fetch.c b/src/rrd_fetch.c index 4ea2eb1..c745f06 100644 --- a/src/rrd_fetch.c +++ b/src/rrd_fetch.c @@ -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", diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 300fdbe..1e597d1 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -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); diff --git a/src/rrd_graph.h b/src/rrd_graph.h index 2b1c05b..c21f356 100644 --- a/src/rrd_graph.h +++ b/src/rrd_graph.h @@ -210,6 +210,7 @@ typedef struct image_desc_t { char *imginfo; /* construct an ]\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
]\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" diff --git a/src/rrd_tool.h b/src/rrd_tool.h index 0be66e4..63359b6 100644 --- a/src/rrd_tool.h +++ b/src/rrd_tool.h @@ -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) -- 2.11.0