char *printstrftime( long argc, const char **args) { rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; char formatted[MAX_STRFTIME_SIZE]; struct tm *the_tm; time_t start_tmp, end_tmp; /* Make sure that we were given the right number of args */ if (argc != 4) { rrd_set_error("wrong number of args %d", argc); return stralloc(""); } /* Init start and end time */ rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); /* Parse the start and end times we were given */ if ((parsetime_error = rrd_parsetime(args[1], &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return stralloc(""); } if ((parsetime_error = rrd_parsetime(args[2], &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return stralloc(""); } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return stralloc(""); } /* Do we do the start or end */ if (strcasecmp(args[0], "START") == 0) { the_tm = localtime(&start_tmp); } else if (strcasecmp(args[0], "END") == 0) { the_tm = localtime(&end_tmp); } else { rrd_set_error("start/end not found in '%s'", args[0]); return stralloc(""); } /* now format it */ if (strftime(formatted, MAX_STRFTIME_SIZE, args[3], the_tm)) { return (stralloc(formatted)); } else { rrd_set_error("strftime failed"); return stralloc(""); } }
int rrd_xport( int argc, char **argv, int UNUSED(*xsize), time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data) { /* two dimensional array containing the data */ image_desc_t im; time_t start_tmp = 0, end_tmp = 0; rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; struct optparse options; optparse_init(&options, argc, argv); struct optparse_long longopts[] = { {"start", 's', OPTPARSE_REQUIRED}, {"end", 'e', OPTPARSE_REQUIRED}, {"maxrows",'m', OPTPARSE_REQUIRED}, {"step", 261, OPTPARSE_REQUIRED}, {"enumds", 262, OPTPARSE_NONE}, {"json", 263, OPTPARSE_NONE}, {"showtime", 't', OPTPARSE_NONE}, {"daemon", 'd', OPTPARSE_REQUIRED}, {0} }; rrd_graph_init(&im); rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); int enumds=0; int json=0; int showtime=0; int opt; while ((opt = optparse_long(&options,longopts,NULL)) != -1){ switch (opt) { case 261: im.step = atoi(options.optarg); break; case 262: enumds=1; break; case 263: json=1; break; case 't': showtime=1; break; case 's': if ((parsetime_error = rrd_parsetime(options.optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(options.optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'm': im.xsize = atol(options.optarg); if (im.xsize < 10) { rrd_set_error("maxrows below 10 rows"); return -1; } break; case 'd': { if (im.daemon_addr != NULL) { rrd_set_error ("You cannot specify --daemon " "more than once."); return (-1); } im.daemon_addr = strdup(options.optarg); if (im.daemon_addr == NULL) { rrd_set_error("strdup error"); return -1; } break; } case '?': rrd_set_error("%s", options.errmsg); return -1; } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980 (%ld)", start_tmp); return -1; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return -1; } im.start = start_tmp; im.end = end_tmp; im.step = max((long) im.step, (im.end - im.start) / im.xsize); rrd_graph_script(options.argc, options.argv, &im, options.optind); if (rrd_test_error()) { im_free(&im); return -1; } if (im.gdes_c == 0) { rrd_set_error("can't make an xport without contents"); im_free(&im); return (-1); } { /* try to connect to rrdcached */ int status = rrdc_connect(im.daemon_addr); if (status != 0) return status; } if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data,0) == -1) { im_free(&im); return -1; } /* and create the export */ if (!xsize) { int flags=0; if (json) { flags|=1; } if (showtime) { flags|=2; } if (enumds) { flags|=4; } stringbuffer_t buffer={0,0,NULL,stdout}; rrd_xport_format_xmljson(flags,&buffer,&im, *start, *end, *step, *col_cnt, *legend_v, *data); } im_free(&im); return 0; }
static graph_desc_t* newGraphDescription(image_desc_t *const im,enum gf_en gf,parsedargs_t* pa,uint64_t bits) { /* check that none of the other bitfield marker is set */ if ((bits&PARSE_FIELD1)&&((bits&(PARSE_FIELD2|PARSE_FIELD3|PARSE_FIELD4)))) { rrd_set_error("newGraphDescription: bad bitfield1 value %08llx",bits);return NULL; } /* the normal handler that adds to img */ if ((!(bits & PARSE_RETRY)) && (gdes_alloc(im))) { return NULL; } /* set gdp */ graph_desc_t *gdp= &im->gdes[im->gdes_c - 1]; /* set some generic things */ gdp->gf=gf; { char *t,*x; long debug=0; if ((t=getKeyValueArgument("debug",1,pa)) && ((getLong(t,&debug,&x,10)))) { rrd_set_error("Bad debug value: %s",t); return NULL; } gdp->debug=debug; } /* and the "flagged" parser implementation * * first the fields with legacy positional args */ #define bitscmp(v) ((bits&v)==v) char* vname=NULL; if (bitscmp(PARSE_VNAME)) { vname=getKeyValueArgument("vname",1,pa); dprintfparsed("got vname: %s\n",vname);} char *rrd=NULL; if (bitscmp(PARSE_RRD)) { rrd=getKeyValueArgument("rrd",1,pa); dprintfparsed("got rrd: %s\n",rrd);} char *ds=NULL; if (bitscmp(PARSE_DS)) { ds=getKeyValueArgument("ds",1,pa); dprintfparsed("got ds: %s\n",ds);} char *cf=NULL; if (bitscmp(PARSE_CF)) { cf=getKeyValueArgument("cf",1,pa); dprintfparsed("got cf: %s\n",cf);} char *color=NULL; if (bitscmp(PARSE_COLOR)) { color=getKeyValueArgument("color",1,pa); dprintfparsed("got color: %s\n",color);} char *color2=NULL; if (bitscmp(PARSE_COLOR2)) { color2=getKeyValueArgument("color2",1,pa); dprintfparsed("got color2: %s\n",color2);} char *rpn=NULL; if (bitscmp(PARSE_RPN)) { rpn=getKeyValueArgument("rpn",1,pa); dprintfparsed("got rpn: %s\n",rpn);} char *legend=NULL; if (bitscmp(PARSE_LEGEND)) { legend=getKeyValueArgument("legend",1,pa); dprintfparsed("got legend: \"%s\"\n",legend);} char *fraction=NULL; if (bitscmp(PARSE_FRACTION)) { fraction=getKeyValueArgument("fraction",1,pa); dprintfparsed("got fraction: %s\n",fraction);} /* * here the ones without delayed assigns (which are for positional parsers) */ if (bitscmp(PARSE_FORMAT)) { char *format=getKeyValueArgument("format",1,pa); if(format) { strncpy(gdp->format,format,FMT_LEG_LEN); dprintfparsed("got format: %s\n",format); } } if (bitscmp(PARSE_STRFTIMEVFMT)) { char *strft=getKeyValueArgument("strftime",1,pa); char *frmtr=getKeyValueArgument("vformatter",1,pa); gdp->strftm=(strft)?1:0; if (frmtr != NULL) { if (strcmp(frmtr,"timestamp") == 0) { gdp->vformatter = VALUE_FORMATTER_TIMESTAMP; } else if (strcmp(frmtr,"duration") == 0) { gdp->vformatter = VALUE_FORMATTER_DURATION; } else { rrd_set_error("Unsupported vformatter: %s", frmtr); return NULL; } } dprintfparsed("got strftime: %s\n",strft); } if (bitscmp(PARSE_STACK)) { char *stack=getKeyValueArgument("stack",1,pa); gdp->stack=(stack)?1:0; dprintfparsed("got stack: %s\n",stack); } if (bitscmp(PARSE_SKIPSCALE)) { char *skipscale=getKeyValueArgument("skipscale",1,pa); gdp->skipscale =(skipscale)?1:0; dprintfparsed("got skipscale: %s\n",skipscale); } if (bitscmp(PARSE_REDUCE)) { char *reduce=getKeyValueArgument("reduce",1,pa); if (reduce) { gdp->cf_reduce=cf_conv(reduce); gdp->cf_reduce_set=1; dprintfparsed("got reduce: %s (%i)\n",reduce,gdp->cf_reduce); if (((int)gdp->cf_reduce)==-1) { rrd_set_error("bad reduce CF: %s",reduce); return NULL; } } } if (bitscmp(PARSE_DAEMON)) { char *daemon=getKeyValueArgument("daemon",1,pa); if (daemon) { strncpy(gdp->daemon,daemon,strlen(daemon)); dprintfparsed("got daemon: %s\n", gdp->daemon); } } if (bitscmp(PARSE_XAXIS)) { long xaxis=0; char *t,*x; if ((t=getKeyValueArgument("xaxis",1,pa)) && ((getLong(t,&xaxis,&x,10))||(xaxis<1)||(xaxis>MAX_AXIS))) { rrd_set_error("Bad xaxis value: %s",t); return NULL; } dprintfparsed("got xaxis: %s (%li)\n",t,xaxis); gdp->xaxisidx=xaxis; } if (bitscmp(PARSE_YAXIS)) { long yaxis=0; char *t,*x; if ((t=getKeyValueArgument("yaxis",1,pa)) && ((getLong(t,&yaxis,&x,10))||(yaxis<1)||(yaxis>MAX_AXIS))) { rrd_set_error("Bad yaxis value: %s",t); return NULL; } dprintfparsed("got yaxis: %s (%li)\n",t,yaxis); gdp->yaxisidx=yaxis; } if (bitscmp(PARSE_LINEWIDTH)) { double linewidth = 1; char *t,*x; if ((t=getKeyValueArgument("linewidth",1,pa))&&(*t!=0)) { if ((getDouble(t,&linewidth,&x))||(linewidth<=0)) { rrd_set_error("Bad line width: %s",t); return NULL; } } dprintfparsed("got linewidth: %s (%g)\n",t,linewidth); gdp->linewidth=linewidth; } if (bitscmp(PARSE_GRADHEIGHT)) { double gradheight=0; char *t,*x; if ((t=getKeyValueArgument("gradheight",1,pa))&&(*t!=0)) { if (getDouble(t,&gradheight,&x)) { rrd_set_error("Bad gradheight: %s",t); return NULL; } dprintfparsed("got gradheight: %s (%g)\n",t,gradheight); gdp->gradheight=gradheight; } } if (bitscmp(PARSE_STEP)) { long step=0; char *t,*x; if ((t=getKeyValueArgument("step",1,pa)) && ((getLong(t,&step,&x,10))||(step<1))) { rrd_set_error("Bad step value: %s",t); return NULL; } dprintfparsed("got step: %s (%li)\n",t,step); gdp->step=step; } if ((bitscmp(PARSE_START)||bitscmp(PARSE_END))) { /* these should get done together to use the start/end code correctly*/ char* parsetime_error; /* first start */ char* start; rrd_time_value_t start_tv; start_tv.type = ABSOLUTE_TIME; start_tv.offset = 0; localtime_r(&gdp->start, &start_tv.tm); if (bitscmp(PARSE_START)) { start=getKeyValueArgument("start",1,pa); if ((start)&&(parsetime_error = rrd_parsetime(start, &start_tv))) { rrd_set_error("start time: %s", parsetime_error);return NULL; } dprintfparsed("got start: %s\n",start); } else { start = NULL; } /* now end */ char* end; rrd_time_value_t end_tv; end_tv.type = ABSOLUTE_TIME; end_tv.offset = 0; localtime_r(&gdp->end, &end_tv.tm); if (bitscmp(PARSE_END)) { end=getKeyValueArgument("end",1,pa); if ((end)&&(parsetime_error = rrd_parsetime(end, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return NULL; } dprintfparsed("got end: %s\n",end); } else { end = NULL; } /* and now put the pieces together (relative times like start=end-2days) */ time_t start_tmp = 0, end_tmp = 0; if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return NULL; } dprintfparsed("got start %s translated to: %lld\n",start,(long long int)start_tmp); dprintfparsed("got end %s translated to: %lld\n",end,(long long int)end_tmp); /* check some ranges */ if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be " "after 1980 (%ld)", start_tmp); return NULL; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return NULL; } /* and finally set it irrespectively of if it has been set or not * it may have been a relative time and if you just set it partially * then that is wrong... */ gdp->start = start_tmp; gdp->start_orig = start_tmp; gdp->end = end_tmp; gdp->end_orig = end_tmp; } if (bitscmp(PARSE_DASHES)) { char* dashes=getKeyValueArgument("dashes",1,pa); /* if we got dashes */ if (dashes) { gdp->dash = 1; gdp->offset = 0; /* count the , in dashes */ int cnt=0;for(char*t=dashes;(*t)&&(t=strchr(t,','));t++,cnt++) {;} dprintfparsed("Got dashes argument: %s with %i comma\n",dashes,cnt); /* now handle */ gdp->ndash = cnt+1; gdp->p_dashes = (double *) malloc(sizeof(double)*(gdp->ndash+1)); /* now loop dashes */ for(int i=0;i<gdp->ndash;i++) { char *x; int f=getDouble(dashes,&gdp->p_dashes[i],&x); if(f<0) { rrd_set_error("Could not parse number: %s",dashes); return NULL; } /* we should have this most of the time */ dprintfparsed("Processed %s to %g at index %i\n",dashes,gdp->p_dashes[i],i); if (f>0) { if (*x!=',') { rrd_set_error("expected a ',' at : %s",x); return NULL;} dashes=x+1; } if ((f==0)&&(i!=gdp->ndash-1)) { rrd_set_error("unexpected end at : %s",dashes); return NULL;} } } char* dashoffset=getKeyValueArgument("dash-offset",1,pa); if (dashoffset) { char* x; if (getDouble(dashoffset,&gdp->offset,&x)) { rrd_set_error("Could not parse dash-offset: %s",dashoffset); return NULL; } } } /* here now the positional(=legacy) parsers which are EXCLUSIVE - SO ELSE IF !!! * we also only parse the extra here and assign just further down * TODO maybe we can generalize this a bit more... */ if (bitscmp(PARSE_VNAMERRDDSCF)) { if ((!vname)||(!rrd)) { /* get the first unused argument */ keyvalue_t* first=getFirstUnusedArgument(1,pa); if (!first) { rrd_set_error("No argument for definition of vdef/rrd in %s",pa->arg_orig); return NULL; } dprintfparsed("got positional vname and rrd: %s - %s\n",first->key,first->value); if (!vname) {vname=first->key;} if (!rrd) {rrd=first->value; } } /* and now look for datasource */ if (!ds) { /* get the first unused argument */ keyvalue_t* first=getFirstUnusedArgument(1,pa); if (!first) { rrd_set_error("No argument for definition of DS in %s",pa->arg_orig); return NULL; } dprintfparsed("got positional ds: %s - \n",first->value); ds=first->value; } /* and for CF */ if (!cf) { /* get the first unused argument */ keyvalue_t* first=getFirstUnusedArgument(1,pa); if (!first) { rrd_set_error("No argument for definition of CF in %s",pa->arg_orig); return NULL; } dprintfparsed("got positional cf: %s - \n",first->value); cf=first->value; } } else if (bitscmp(PARSE_VNAMECOLORLEGEND)) { /* vname */ if (!vname) { keyvalue_t* first=getFirstUnusedArgument(1,pa); if (first) { vname=first->value; } else { rrd_set_error("No positional VNAME"); return NULL; } } /* fraction added into the parsing mix for TICK */ if ((bitscmp(PARSE_VNAMECOLORFRACTIONLEGEND))&&(!fraction)) { keyvalue_t* first=getFirstUnusedArgument(1,pa); if (first) { fraction=first->value; } else { rrd_set_error("No positional FRACTION"); return NULL; } } /* legend (it's optional if no other arguments follow)*/ if (!legend) { keyvalue_t* first=getFirstUnusedArgument(1,pa); if (first) { legend=first->keyvalue; dprintfparsed("got positional legend: %s - \n",legend); } } } else if (bitscmp(PARSE_VNAMERPN)) { if ((!vname)||(!rpn)) { /* get the first unused argument */ keyvalue_t* first=getFirstUnusedArgument(1,pa); if (!first) { rrd_set_error("No argument for definition of vdef/rrd in %s",pa->arg_orig); return NULL; } dprintfparsed("got positional vname and rpn: %s - %s\n",first->key,first->value); if (!vname) {vname=first->key;} if (!rpn) {rpn=first->value; } } } else if (bitscmp(PARSE_VNAMEREFPOS)) { if ((!vname)) { /* get the first unused argument */ keyvalue_t* first=getFirstUnusedArgument(1,pa); if (!first) { rrd_set_error("No argument for definition of vdef/rrd in %s",pa->arg_orig); return NULL; } dprintfparsed("got positional vname and rrd: %s - %s\n",first->key,first->value); if (!vname) {vname=first->value;} } } /* and set some of those late assignments to accommodate the legacy parser*/ /* first split vname into color */ if (vname) { /* check for color */ char *h1=strchr(vname,'#'); char* h2=NULL; if (h1) { *h1=0;h1++; dprintfparsed("got positional color: %s - \n",h1); h2=strchr(h1,'#'); if (h2) { *h2=0;h2++; dprintfparsed("got positional color2: %s - \n",h2); } } if (bitscmp(PARSE_COLOR) && (! color) && (h1)) { color=h1;} if (bitscmp(PARSE_COLOR2) && (! color2) && (h2)) { color2=h2;} } /* check if we are reusing the vname */ if (vname) { int idx=find_var(im, vname); dprintfparsed("got positional index %i for %s - \n",idx,vname); /* some handling */ if (bitscmp(PARSE_VNAMEDEF)) { if (idx>=0) { rrd_set_error("trying to reuse vname %s",vname); return NULL; } } else if (bitscmp(PARSE_VNAMEREF)) { gdp->vidx=idx; if (idx < 0){ if (bitscmp(PARSE_VNAMEREFNUM)) { double val; char *x; int f=getDouble(vname,&val,&x); if (f) { rrd_set_error("%s is not a vname nor a number",vname); return NULL; } if (gf==GF_VRULE){ gdp->xrule=val; } else { gdp->yrule=val; } } else { rrd_set_error("vname %s not found",vname); return NULL; } } } } /* and assign it */ if (vname) { strncpy(gdp->vname,vname,MAX_VNAME_LEN); gdp->vname[MAX_VNAME_LEN] = '\0'; } if (rrd) { strncpy(gdp->rrd,rrd, 1023); gdp->rrd[1023] = '\0'; } if (ds) { strncpy(gdp->ds_nam,ds,DS_NAM_SIZE - 1); gdp->ds_nam[DS_NAM_SIZE - 1] = '\0'; } if (cf) { gdp->cf=cf_conv(cf); if (((int)gdp->cf)==-1) { rrd_set_error("bad CF: %s",cf); return NULL; } } else { if (bitscmp(PARSE_CF)) { gdp->cf = (enum cf_en) -1; }} if ((color)&&(parse_color(color,&(gdp->col)))) { return NULL; } if ((color2)&&(parse_color(color2,&(gdp->col2)))) { return NULL; } if (rpn) {gdp->rpn=rpn;} if ((legend)&&(*legend!=0)) { /* and copy it into place */ strncpy(gdp->legend,legend,FMT_LEG_LEN); } if (fraction) { if (strcmp(fraction,"vname")==0) { /* check that vname is really a DEF|CDEF */ if (im->gdes[gdp->vidx].gf != GF_DEF && im->gdes[gdp->vidx].gf != GF_CDEF) { rrd_set_error("variable '%s' not DEF nor CDEF when using dynamic fractions", gdp->vname); return NULL; } /* add as flag to use (c)?def */ gdp->cf=CF_LAST; gdp->yrule=0.5; } else { /* parse number */ double val; char *x; int f=getDouble(fraction,&val,&x); if (f) { rrd_set_error("error parsing number %s",vname); return NULL; } gdp->yrule=val; } } /* remember the index for faster varfind */ char *key = gdes_fetch_key((*gdp)); if (gdp->gf == GF_DEF && !g_hash_table_lookup_extended(im->rrd_map,key,NULL,NULL)){ dprintfhash("ins key %s - %ld\n",key,im->gdes_c-1); g_hash_table_insert(im->gdef_map,g_strdup(key),GINT_TO_POINTER(im->gdes_c-1)); } free(key); if (gdp->gf == GF_DEF || gdp->gf == GF_VDEF || gdp->gf == GF_CDEF){ dprintfhash("ins vname %s - %ld\n",gdp->vname,im->gdes_c-1); g_hash_table_insert(im->gdef_map,g_strdup(gdp->vname),GINT_TO_POINTER(im->gdes_c-1)); } return gdp; }
int rrd_create( int argc, char **argv) { struct option long_options[] = { {"start", required_argument, 0, 'b'}, {"step", required_argument, 0, 's'}, {"no-overwrite", no_argument, 0, 'O'}, {0, 0, 0, 0} }; int option_index = 0; int opt; time_t last_up = time(NULL) - 10; unsigned long pdp_step = 300; rrd_time_value_t last_up_tv; char *parsetime_error = NULL; long long_tmp; int rc; optind = 0; opterr = 0; /* initialize getopt */ while (1) { opt = getopt_long(argc, argv, "Ob:s:", long_options, &option_index); if (opt == EOF) break; switch (opt) { case 'b': if ((parsetime_error = rrd_parsetime(optarg, &last_up_tv))) { rrd_set_error("start time: %s", parsetime_error); return (-1); } if (last_up_tv.type == RELATIVE_TO_END_TIME || last_up_tv.type == RELATIVE_TO_START_TIME) { rrd_set_error("specifying time relative to the 'start' " "or 'end' makes no sense here"); return (-1); } last_up = mktime(&last_up_tv.tm) +last_up_tv.offset; if (last_up < 3600 * 24 * 365 * 10) { rrd_set_error ("the first entry to the RRD should be after 1980"); return (-1); } break; case 's': long_tmp = atol(optarg); if (long_tmp < 1) { rrd_set_error("step size should be no less than one second"); return (-1); } pdp_step = long_tmp; break; case 'O': opt_no_overwrite = 1; break; case '?': if (optopt != 0) rrd_set_error("unknown option '%c'", optopt); else rrd_set_error("unknown option '%s'", argv[optind - 1]); return (-1); } } if (optind == argc) { rrd_set_error("need name of an rrd file to create"); return -1; } rc = rrd_create_r(argv[optind], pdp_step, last_up, argc - optind - 1, (const char **) (argv + optind + 1)); return rc; }
int rrd_fetch( int argc, char **argv, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ 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 */ unsigned long step_tmp = 1; time_t start_tmp = 0, end_tmp = 0; const char *cf; char *opt_daemon = NULL; int align_start = 0; int status; rrd_time_value_t start_tv, end_tv; const char *parsetime_error = NULL; struct option long_options[] = { {"resolution", required_argument, 0, 'r'}, {"start", required_argument, 0, 's'}, {"end", required_argument, 0, 'e'}, {"align-start", optional_argument, 0, 'a'}, {"daemon", required_argument, 0, 'd'}, {0, 0, 0, 0} }; optind = 0; opterr = 0; /* initialize getopt */ /* init start and end time */ rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); while (1) { int option_index = 0; int opt; opt = getopt_long(argc, argv, "ar:s:e:d:", long_options, &option_index); if (opt == EOF) break; switch (opt) { case 's': if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'a': align_start = 1; break; case 'r': if ((parsetime_error = rrd_scaled_duration(optarg, 1, &step_tmp))) { rrd_set_error("resolution: %s", parsetime_error); return -1; } break; case 'd': if (opt_daemon != NULL) free (opt_daemon); opt_daemon = strdup (optarg); if (opt_daemon == NULL) { rrd_set_error ("strdup failed."); return (-1); } break; case '?': rrd_set_error("unknown option '-%c'", optopt); return (-1); } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980"); return (-1); } if (align_start) { time_t delta = (start_tmp % step_tmp); start_tmp -= delta; end_tmp -= delta; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return (-1); } *start = start_tmp; *end = end_tmp; *step = step_tmp; if (optind + 1 >= argc) { rrd_set_error("Usage: rrdtool %s <file> <CF> [options]", argv[0]); return -1; } cf = argv[optind + 1]; rrdc_connect (opt_daemon); if (rrdc_is_connected (opt_daemon)) status = rrdc_fetch (argv[optind], cf, start, end, step, ds_cnt, ds_namv, data); else status = rrd_fetch_r(argv[optind], cf, start, end, step, ds_cnt, ds_namv, data); if (status != 0) return (-1); return (0); }
int rrd_xport( int argc, char **argv, int UNUSED(*xsize), time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data) { /* two dimensional array containing the data */ image_desc_t im; time_t start_tmp = 0, end_tmp = 0; rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; struct option long_options[] = { {"start", required_argument, 0, 's'}, {"end", required_argument, 0, 'e'}, {"maxrows", required_argument, 0, 'm'}, {"step", required_argument, 0, 261}, {"enumds", no_argument, 0, 262}, /* these are handled in the frontend ... */ {"json", no_argument, 0, 263}, /* these are handled in the frontend ... */ {"daemon", required_argument, 0, 'd'}, {0, 0, 0, 0} }; optind = 0; opterr = 0; /* initialize getopt */ rrd_graph_init(&im); rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); int enumds=0; int json=0; while (1) { int option_index = 0; int opt; opt = getopt_long(argc, argv, "s:e:m:d:", long_options, &option_index); if (opt == EOF) break; switch (opt) { case 261: im.step = atoi(optarg); break; case 262: enumds=1; break; case 263: json=1; break; case 's': if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'm': im.xsize = atol(optarg); if (im.xsize < 10) { rrd_set_error("maxrows below 10 rows"); return -1; } break; case 'd': { if (im.daemon_addr != NULL) { rrd_set_error ("You cannot specify --daemon " "more than once."); return (-1); } im.daemon_addr = strdup(optarg); if (im.daemon_addr == NULL) { rrd_set_error("strdup error"); return -1; } break; } case '?': rrd_set_error("unknown option '%s'", argv[optind - 1]); return -1; } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980 (%ld)", start_tmp); return -1; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return -1; } im.start = start_tmp; im.end = end_tmp; im.step = max((long) im.step, (im.end - im.start) / im.xsize); rrd_graph_script(argc, argv, &im, 0); if (rrd_test_error()) { im_free(&im); return -1; } if (im.gdes_c == 0) { rrd_set_error("can't make an xport without contents"); im_free(&im); return (-1); } { /* try to connect to rrdcached */ int status = rrdc_connect(im.daemon_addr); if (status != 0) return status; } if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data,0) == -1) { im_free(&im); return -1; } /* and create the export */ if (!xsize) { int flags=0; if (json) { flags|=1; } if (enumds) { flags|=4; } stringbuffer_t buffer={0,0,NULL,stdout}; rrd_xport_format_xmljson(flags,&buffer,&im, *start, *end, *step, *col_cnt, *legend_v, *data); } im_free(&im); return 0; }
int rrd_fetch( int argc, char **argv, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ 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 */ long step_tmp = 1; time_t start_tmp = 0, end_tmp = 0; const char *cf; rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; struct option long_options[] = { {"resolution", required_argument, 0, 'r'}, {"start", required_argument, 0, 's'}, {"end", required_argument, 0, 'e'}, {0, 0, 0, 0} }; optind = 0; opterr = 0; /* initialize getopt */ /* init start and end time */ rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); while (1) { int option_index = 0; int opt; opt = getopt_long(argc, argv, "r:s:e:", long_options, &option_index); if (opt == EOF) break; switch (opt) { case 's': if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'r': step_tmp = atol(optarg); break; case '?': rrd_set_error("unknown option '-%c'", optopt); return (-1); } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980"); return (-1); } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return (-1); } *start = start_tmp; *end = end_tmp; if (step_tmp < 1) { rrd_set_error("step must be >= 1 second"); return -1; } *step = step_tmp; if (optind + 1 >= argc) { rrd_set_error("not enough arguments"); return -1; } cf = argv[optind + 1]; if (rrd_fetch_r(argv[optind], cf, start, end, step, ds_cnt, ds_namv, data) != 0) return (-1); return (0); }
int rrd_fetch( int argc, char **argv, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ 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 */ unsigned long step_tmp = 1; time_t start_tmp = 0, end_tmp = 0; const char *cf; char *opt_daemon = NULL; int align_start = 0; int status; rrd_time_value_t start_tv, end_tv; const char *parsetime_error = NULL; struct optparse_long longopts[] = { {"resolution", 'r', OPTPARSE_REQUIRED}, {"start", 's', OPTPARSE_REQUIRED}, {"end", 'e', OPTPARSE_REQUIRED}, {"align-start", 'a', OPTPARSE_NONE}, {"daemon", 'd', OPTPARSE_REQUIRED}, {0}, }; struct optparse options; int opt; /* init start and end time */ rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); optparse_init(&options, argc, argv); while ((opt = optparse_long(&options, longopts, NULL)) != -1) { switch (opt) { case 's': if ((parsetime_error = rrd_parsetime(options.optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(options.optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'a': align_start = 1; break; case 'r': if ((parsetime_error = rrd_scaled_duration(options.optarg, 1, &step_tmp))) { rrd_set_error("resolution: %s", parsetime_error); return -1; } break; case 'd': if (opt_daemon != NULL) free (opt_daemon); opt_daemon = strdup(options.optarg); if (opt_daemon == NULL) { rrd_set_error ("strdup failed."); return -1; } break; case '?': rrd_set_error("%s", options.errmsg); return -1; } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980"); return (-1); } if (align_start) { time_t delta = (start_tmp % step_tmp); start_tmp -= delta; end_tmp -= delta; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return (-1); } *start = start_tmp; *end = end_tmp; *step = step_tmp; if (options.optind + 1 >= options.argc) { rrd_set_error("Usage: rrdtool %s <file> <CF> [options]", options.argv[0]); return -1; } cf = options.argv[options.optind + 1]; rrdc_connect (opt_daemon); if (rrdc_is_connected (opt_daemon)) status = rrdc_fetch (options.argv[options.optind], cf, start, end, step, ds_cnt, ds_namv, data); else status = rrd_fetch_r(options.argv[options.optind], cf, start, end, step, ds_cnt, ds_namv, data); if (status != 0) return (-1); return (0); }
int rrd_xport( int argc, char **argv, int UNUSED(*xsize), time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data) { /* two dimensional array containing the data */ image_desc_t im; time_t start_tmp = 0, end_tmp = 0; rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; struct option long_options[] = { {"start", required_argument, 0, 's'}, {"end", required_argument, 0, 'e'}, {"maxrows", required_argument, 0, 'm'}, {"step", required_argument, 0, 261}, {"enumds", no_argument, 0, 262}, /* these are handled in the frontend ... */ {0, 0, 0, 0} }; optind = 0; opterr = 0; /* initialize getopt */ rrd_graph_init(&im); rrd_parsetime("end-24h", &start_tv); rrd_parsetime("now", &end_tv); while (1) { int option_index = 0; int opt; opt = getopt_long(argc, argv, "s:e:m:", long_options, &option_index); if (opt == EOF) break; switch (opt) { case 261: im.step = atoi(optarg); break; case 262: break; case 's': if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) { rrd_set_error("start time: %s", parsetime_error); return -1; } break; case 'e': if ((parsetime_error = rrd_parsetime(optarg, &end_tv))) { rrd_set_error("end time: %s", parsetime_error); return -1; } break; case 'm': im.xsize = atol(optarg); if (im.xsize < 10) { rrd_set_error("maxrows below 10 rows"); return -1; } break; case '?': rrd_set_error("unknown option '%s'", argv[optind - 1]); return -1; } } if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) { return -1; } if (start_tmp < 3600 * 24 * 365 * 10) { rrd_set_error("the first entry to fetch should be after 1980 (%ld)", start_tmp); return -1; } if (end_tmp < start_tmp) { rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp); return -1; } im.start = start_tmp; im.end = end_tmp; im.step = max((long) im.step, (im.end - im.start) / im.xsize); rrd_graph_script(argc, argv, &im, 0); if (rrd_test_error()) { im_free(&im); return -1; } if (im.gdes_c == 0) { rrd_set_error("can't make an xport without contents"); im_free(&im); return (-1); } if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) { im_free(&im); return -1; } im_free(&im); return 0; }