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; }
int rrd_graph_xport(image_desc_t *im) { /* prepare the data for processing */ unsigned long col_cnt=0; time_t start=im->start; time_t end=im->end; unsigned long step=im->step; char **legend_v=NULL; rrd_value_t *data=NULL; /* initialize buffer */ stringbuffer_t buffer={0,0,NULL,NULL}; /* check if we have a supported ggraph format */ switch (im->graph_type) { /* allow the following to pass */ case GTYPE_TIME: case GTYPE_XY: break; default: rrd_set_error("Not supported graph type"); return -1; } /* if we write a file, then open it */ if (im->graphfile) { buffer.file=fopen(im->graphfile,"w"); } /* do the data processing */ if (rrd_xport_fn(im,&start,&end,&step,&col_cnt,&legend_v,&data,1)) { return -1;} /* fill in some data */ rrd_infoval_t info; info.u_cnt = start; grinfo_push(im, sprintf_alloc("graph_start"), RD_I_CNT, info); info.u_cnt = end; grinfo_push(im, sprintf_alloc("graph_end"), RD_I_CNT, info); info.u_cnt = step; grinfo_push(im, sprintf_alloc("graph_step"), RD_I_CNT, info); /* set locale */ /* format it for output */ int r=0; switch(im->imgformat) { case IF_XML: r=rrd_xport_format_xmljson(2,&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_XMLENUM: r=rrd_xport_format_xmljson(6,&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_JSON: r=rrd_xport_format_xmljson(1,&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_JSONTIME: r=rrd_xport_format_xmljson(3,&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_CSV: r=rrd_xport_format_sv(',',&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_TSV: r=rrd_xport_format_sv('\t',&buffer,im, start, end, step, col_cnt, legend_v, data); break; case IF_SSV: r=rrd_xport_format_sv(';',&buffer,im, start, end, step, col_cnt, legend_v, data); break; default: break; } /* handle errors */ if (r) { /* free legend */ for (unsigned long j = 0; j < col_cnt; j++) { free(legend_v[j]); } free(legend_v); /* free data */ free(data); /* free the buffer */ if (buffer.data) {free(buffer.data);} /* close the file */ if (buffer.file) {fclose(buffer.file);} /* and return with error */ return r; } /* now do the cleanup */ if (buffer.file) { fclose(buffer.file); buffer.file=NULL; im->rendered_image_size=0; im->rendered_image=NULL; } else { im->rendered_image_size=buffer.len; im->rendered_image=buffer.data; } /* and print stuff */ return print_calc(im); }
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; }
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; }
/* mostly rrd_graph(), just pushed a bit here and stretched a bit there */ int rrd_xport(int argc, char **argv, int *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; int i; long long_tmp; time_t start_tmp=0,end_tmp=0; char symname[100]; long scancount; struct rrd_time_value start_tv, end_tv; char *parsetime_error = NULL; parsetime("end-24h", &start_tv); parsetime("now", &end_tv); /* use the default values from rrd_graph.c */ im.xlab_user.minsec = -1; im.xgif=0; im.ygif=0; im.xsize = 400; im.ysize = 100; im.step = 0; im.ylegend[0] = '\0'; im.title[0] = '\0'; im.minval = DNAN; im.maxval = DNAN; im.interlaced = 0; im.unitsexponent= 9999; im.unitslength= 9; im.extra_flags= 0; im.rigid = 0; im.imginfo = NULL; im.lazy = 0; im.logarithmic = 0; im.ygridstep = DNAN; im.draw_x_grid = 1; im.draw_y_grid = 1; im.base = 1000; im.prt_c = 0; im.gdes_c = 0; im.gdes = NULL; im.imgformat = IF_GIF; /* we default to GIF output */ while (1) { static struct option long_options[] = { {"start", required_argument, 0, 's'}, {"end", required_argument, 0, 'e'}, {"maxrows", required_argument, 0, 'm'}, {"step", required_argument, 0, 261}, {0,0,0,0} }; 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 's': if ((parsetime_error = parsetime(optarg, &start_tv))) { rrd_set_error( "start time: %s", parsetime_error ); return -1; } break; case 'e': if ((parsetime_error = parsetime(optarg, &end_tv))) { rrd_set_error( "end time: %s", parsetime_error ); return -1; } break; case 'm': long_tmp = atol(optarg); if (long_tmp < 10) { rrd_set_error("maxrows below 10 rows"); return -1; } im.xsize = long_tmp; 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("missing filename"); return -1; } */ if (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; for(i=optind; i<argc; i++) { int argstart=0; int strstart=0; char varname[30],*rpnex; gdes_alloc(&im); if(sscanf(argv[i],"%10[A-Z0-9]:%n",symname,&argstart)==1) { if((im.gdes[im.gdes_c-1].gf=gf_conv(symname))==-1) { im_free(&im); rrd_set_error("unknown function '%s'",symname); return -1; } } else { rrd_set_error("can't parse '%s'",argv[i]); im_free(&im); return -1; } switch(im.gdes[im.gdes_c-1].gf) { case GF_CDEF: if((rpnex = malloc(strlen(&argv[i][argstart])*sizeof(char)))==NULL) { rrd_set_error("malloc for CDEF"); return -1; } if(sscanf( &argv[i][argstart], DEF_NAM_FMT "=%[^: ]", im.gdes[im.gdes_c-1].vname, rpnex) != 2) { im_free(&im); free(rpnex); rrd_set_error("can't parse CDEF '%s'",&argv[i][argstart]); return -1; } /* checking for duplicate DEF CDEFS */ if(find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) { im_free(&im); rrd_set_error("duplicate variable '%s'", im.gdes[im.gdes_c-1].vname); return -1; } if((im.gdes[im.gdes_c-1].rpnp = str2rpn(&im,rpnex))== NULL) { rrd_set_error("invalid rpn expression '%s'", rpnex); im_free(&im); return -1; } free(rpnex); break; case GF_DEF: if (sscanf( &argv[i][argstart], DEF_NAM_FMT "=%n", im.gdes[im.gdes_c-1].vname, &strstart)== 1 && strstart) { /* is the = did not match %n returns 0 */ if(sscanf(&argv[i][argstart +strstart +scan_for_col(&argv[i][argstart+strstart], MAXPATH,im.gdes[im.gdes_c-1].rrd)], ":" DS_NAM_FMT ":" CF_NAM_FMT, im.gdes[im.gdes_c-1].ds_nam, symname) != 2) { im_free(&im); rrd_set_error("can't parse DEF '%s' -2",&argv[i][argstart]); return -1; } } else { im_free(&im); rrd_set_error("can't parse DEF '%s'",&argv[i][argstart]); return -1; } /* checking for duplicate DEF CDEFS */ if (find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) { im_free(&im); rrd_set_error("duplicate variable '%s'", im.gdes[im.gdes_c-1].vname); return -1; } if((im.gdes[im.gdes_c-1].cf=cf_conv(symname))==-1) { im_free(&im); rrd_set_error("unknown cf '%s'",symname); return -1; } break; case GF_XPORT: if((scancount=sscanf( &argv[i][argstart], "%29[^:]:%n", varname, &strstart))>=1) { if(strstart <= 0) { im.gdes[im.gdes_c-1].legend[0] = '\0'; } else { scan_for_col(&argv[i][argstart+strstart],FMT_LEG_LEN,im.gdes[im.gdes_c-1].legend); } if((im.gdes[im.gdes_c-1].vidx=find_var(&im,varname))==-1) { im_free(&im); rrd_set_error("unknown variable '%s'",varname); return -1; } } else { im_free(&im); rrd_set_error("can't parse '%s'",&argv[i][argstart]); return -1; } break; default: break; } } if (im.gdes_c == 0) { rrd_set_error("can't make a graph 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; }