Example #1
0
int main(int argc, char **argv)
{
	if (parse_options(argc, argv) != 0) {
		fprintf(stderr, "USAGE: %s -t start:end <cf> <metric:name:with:ds>\n", argv[0]);
		exit(1);
	}
	if (OPTIONS.DEBUG) {
		fprintf(stderr, " cf      min = %p\n", cf_min);
		fprintf(stderr, " cf      max = %p\n", cf_max);
		fprintf(stderr, " cf      sum = %p\n", cf_sum);
		fprintf(stderr, " cf     mean = %p\n", cf_mean);
		fprintf(stderr, " cf   median = %p\n", cf_median);
		fprintf(stderr, " cf   stddev = %p\n", cf_stddev);
		fprintf(stderr, " cf variance = %p\n", cf_variance);
		fprintf(stderr, " cf      nth = %p\n", cf_nth);

		fprintf(stderr, "-------------------------\n\n\n");
		fprintf(stderr, "metric = %s\n", OPTIONS.metric);
		fprintf(stderr, "    ds = %s\n", OPTIONS.ds);
		fprintf(stderr, "  file = %s\n", OPTIONS.rrdfile);
		fprintf(stderr, "  root = %s\n", OPTIONS.root);
		fprintf(stderr, "  hash = %s\n", OPTIONS.hash);
		fprintf(stderr, " start = %lu\n", OPTIONS.start);
		fprintf(stderr, "   end = %lu\n", OPTIONS.end);
		fprintf(stderr, "    cf = %p\n", OPTIONS.cf);
		if (OPTIONS.cf == cf_nth)
			fprintf(stderr, "     p = %f\n", OPTIONS.cf_arg.percentile);
		if (OPTIONS.cf_arg.skip_unknown)
			fprintf(stderr, "     U = ignore/skip\n");
		else
			fprintf(stderr, "     U = %f\n", OPTIONS.cf_arg.unknown);
		fprintf(stderr, "\n\n");
	}

	char          **ds_names;
	unsigned long   ds_count;
	unsigned long   step = 1;
	rrd_value_t *raw;
	int rc;

	rc = rrd_fetch_r(OPTIONS.rrdfile, "AVERAGE", &OPTIONS.start, &OPTIONS.end, &step,
			&ds_count, &ds_names, &raw);
	if (rc != 0) {
		fprintf(stderr, "fetch failed!\n");
		if (rrd_test_error()) {
			fprintf(stderr, "rrd said: %s\n", rrd_get_error());
		}
		exit(2);
	}

	int ds;
	for (ds = 0; ds < ds_count; ds++)
		if (strcmp(OPTIONS.ds, ds_names[ds]) == 0)
			break;
	if (ds >= ds_count) {
		fprintf(stderr, "DS '%s' not found in RRD file\n", OPTIONS.ds);
		exit(2);
	}

	size_t n = (OPTIONS.end - OPTIONS.start) / step;
	double *set = calloc(n, sizeof(double));
	rrd_value_t *d = raw + ds;
	int i, j;
	for (i = 0, j = 0; i < n; i++) {
		double v = (double)*d;
		if (isnan(v)) {
			if (OPTIONS.cf_arg.skip_unknown) {
				if (OPTIONS.DEBUG)
					fprintf(stderr, "skipping sample #%i (--unknown=ignore)\n", i+1);
				continue;
			}

			if (OPTIONS.DEBUG)
				fprintf(stderr, "sample #%i is UNKNOWN (substituting %e)\n", i+1, OPTIONS.cf_arg.unknown);
			v = OPTIONS.cf_arg.unknown;
		}

		set[j] = v;
		if (OPTIONS.DEBUG)
			fprintf(stderr, "[%i] %e (%lf)\n", j+1, set[j], set[j]);
		d += ds_count;
		j++;
	}
	printf("%e\n", (*OPTIONS.cf)(j, set, &OPTIONS.cf_arg));

	return 0;
}
Example #2
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 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);
}
Example #3
0
static uint64_t _rrd_consolidate_one(time_t t0, time_t t1,
				     char* filename, char* rra_name,
				     bool flag_approximate)
{
	int status, rra_nb = -1;
	unsigned long step = 1, ds_count, ii;
	char cf[] = "AVERAGE";
	char **ds_names;
	time_t ti, start = t0-1, end = t1+1;
	uint32_t nb_miss = 0, nb_values = 0;
	rrd_value_t *rrd_data, *rrd_data_p;
	rrd_value_t current_watt = (rrd_value_t)NO_VAL;
	rrd_value_t temp_energy = 0, consumed_energy = 0;

	last_valid_time = 0;
	last_valid_watt = (rrd_value_t)NO_VAL;

	status = rrd_fetch_r(filename, cf,
			     &start, &end, &step,
			     &ds_count, &ds_names,
			     &rrd_data);

	if (status != 0){
		if (debug_flags & DEBUG_FLAG_EXT_SENSORS)
			info("ext_sensors: error rrd_fetch %s",filename);
		return NO_VAL;
	}

	rrd_data_p = rrd_data;

	do {
		if (start == end) {
			consumed_energy = (rrd_value_t)NO_VAL;
			break;
		}
		if (ds_count == 0) {
			if (debug_flags & DEBUG_FLAG_EXT_SENSORS)
				info("ext_sensors: error ds_count==0 in RRD %s",
				     filename);
			consumed_energy = (rrd_value_t)NO_VAL;
			break;
		} else if (ds_count == 1 || rra_name == NULL)
			rra_nb = 0;
		else {
			for (ii = 0; ii < ds_count; ii++){
				if (!strcmp(ds_names[ii],rra_name)) {
					rra_nb = ii;
					break;
				}
			}
			if (rra_nb == -1) {
				if (debug_flags & DEBUG_FLAG_EXT_SENSORS)
					info("ext_sensors: error RRA %s not "
					     "found in RRD %s",
					     rra_name, filename);
				consumed_energy = (rrd_value_t)NO_VAL;
				break;
			}
		}
		ti = start;
		do {
			for (ii = 0; ii < rra_nb; ii++)
				rrd_data_p++;
			last_valid_watt = _validate_watt(rrd_data_p);
			if (last_valid_watt != (rrd_value_t)NO_VAL)
				last_valid_time = ti;
			for (ii = rra_nb; ii < ds_count; ii++)
				rrd_data_p++;
			ti += step;
		} while (ti < t0 && ti < end);

		if (ti != t0 && ti < end) {
			for (ii = 0; ii < rra_nb; ii++)
				rrd_data_p++;
			current_watt = _validate_watt(rrd_data_p);

			if (current_watt != (rrd_value_t)NO_VAL) {
				temp_energy = _get_additional_consumption(
					t0, ti < t1 ? ti : t1,
					current_watt, current_watt);
				last_valid_watt = current_watt;
				last_valid_time = ti;
				consumed_energy += temp_energy;
				nb_values += 1;
			} else {
				nb_miss += 10001;
			}

			for (ii = rra_nb; ii < ds_count; ii++)
				rrd_data_p++;
		} else if ((ti == t0) && (ti < end)) {
			for (ii = 0; ii < rra_nb; ii++)
				rrd_data_p++;
			current_watt = _validate_watt(rrd_data_p);
			if (current_watt != (rrd_value_t)NO_VAL) {
				last_valid_watt = current_watt;
				last_valid_time = ti;
			}
			for (ii = rra_nb; ii < ds_count; ii++)
				rrd_data_p++;
			ti += step;
		}
		while (((ti += step) <= t1) && (ti < end)) {
			for (ii = 0; ii < rra_nb; ii++)
				rrd_data_p++;
			current_watt = _validate_watt(rrd_data_p);
			if (current_watt != (rrd_value_t)NO_VAL &&
			    last_valid_watt != (rrd_value_t)NO_VAL) {
				temp_energy = _get_additional_consumption(
					ti-step, ti,
					last_valid_watt, current_watt);
				last_valid_watt = current_watt;
				last_valid_time = ti;
				consumed_energy += temp_energy;
				nb_values += 1;
			} else {
				nb_miss += 1;
			}
			for (ii = rra_nb; ii < ds_count; ii++)
				rrd_data_p++;
		}
		if ((ti > t1) && (t1 > (t0 + step)) && (ti-step < t1)) {
			if (current_watt != (rrd_value_t)NO_VAL) {
				temp_energy = _get_additional_consumption(
					ti-step, t1,
					current_watt, current_watt);
				consumed_energy += temp_energy;
				nb_values += 1;
			} else {
				nb_miss += 1;
			}
		}
	} while(0);

	if (nb_miss >= 10000) {
		if (debug_flags & DEBUG_FLAG_EXT_SENSORS)
			info("ext_sensors: RRD: no first value");
		nb_miss -= 10000;
	}
	if (debug_flags & DEBUG_FLAG_EXT_SENSORS)
		info("ext_sensors: RRD: have %d values and miss %d values",
		     nb_values, nb_miss);

	if (flag_approximate &&
	    current_watt == (rrd_value_t)NO_VAL &&
	    last_valid_watt != (rrd_value_t)NO_VAL) {
		temp_energy = _get_additional_consumption(
			last_valid_time, t1,
			last_valid_watt, last_valid_watt);
		consumed_energy += temp_energy;
	}

	for (ii = 0; ii < ds_count; ii++)
		free(ds_names[ii]);

	free(ds_names);
	free(rrd_data);

	return (uint64_t)consumed_energy;
}
Example #4
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);
}
Example #5
0
static sdb_timeseries_t *
sdb_rrd_fetch(const char *id, sdb_timeseries_opts_t *opts,
		sdb_object_t *user_data)
{
	sdb_timeseries_t *ts;

	time_t start = (time_t)SDB_TIME_TO_SECS(opts->start);
	time_t end = (time_t)SDB_TIME_TO_SECS(opts->end);

	unsigned long step = 0;
	unsigned long ds_cnt = 0;
	unsigned long val_cnt = 0;
	char **ds_namv = NULL;
	rrd_value_t *data = NULL;

	if (user_data) {
		/* -> use RRDCacheD */
		char *addr = SDB_OBJ_WRAPPER(user_data)->data;

		if (! rrdcached_connect(addr))
			return NULL;

#ifdef HAVE_RRD_CLIENT_H
		if (rrdc_flush(id)) {
			sdb_log(SDB_LOG_ERR, "Failed to flush '%s' through RRDCacheD: %s",
					id, rrd_get_error());
			return NULL;
		}
#endif
	}

#define FREE_RRD_DATA() \
	do { \
		size_t i; \
		for (i = 0; i < ds_cnt; ++i) \
			rrd_freemem(ds_namv[i]); \
		rrd_freemem(ds_namv); \
		rrd_freemem(data); \
	} while (0)

	/* limit to about 1000 data-points for now
	 * TODO: make this configurable */
	step = (end - start) / 1000;

	if (rrd_fetch_r(id, "AVERAGE", &start, &end, &step,
				&ds_cnt, &ds_namv, &data)) {
		char errbuf[1024];
		sdb_strerror(errno, errbuf, sizeof(errbuf));
		sdb_log(SDB_LOG_ERR, "Failed to fetch data from %s: %s", id, errbuf);
		return NULL;
	}

	val_cnt = (unsigned long)(end - start) / step;

	/* RRDtool does not support fetching specific data-sources, so we'll have
	 * to filter the requested ones after fetching them all */
	if (opts->data_names && opts->data_names_len)
		ts = sdb_timeseries_create(opts->data_names_len,
				(const char * const *)opts->data_names, val_cnt);
	else
		ts = sdb_timeseries_create(ds_cnt, (const char * const *)ds_namv, val_cnt);
	if (! ts) {
		char errbuf[1024];
		sdb_strerror(errno, errbuf, sizeof(errbuf));
		sdb_log(SDB_LOG_ERR, "Failed to allocate time-series object: %s", errbuf);
		FREE_RRD_DATA();
		return NULL;
	}

	ts->start = SECS_TO_SDB_TIME(start + (time_t)step);
	ts->end = SECS_TO_SDB_TIME(end);

	if (copy_data(ts, data, (time_t)step, (size_t)ds_cnt, ds_namv) < 0) {
		FREE_RRD_DATA();
		sdb_timeseries_destroy(ts);
		return NULL;
	}

	FREE_RRD_DATA();
	return ts;
} /* sdb_rrd_fetch */
Example #6
0
File: Rrd.c Project: oetiker/Rrd
/*then returns an R data.frame that contain the RRA values fitting between timestamps startIn (non incl) and sendIn*/
SEXP importRRD(SEXP filenameIn, SEXP cfIn, SEXP startIn, SEXP endIn, SEXP stepIn)  {

    rrd_value_t *data;

    const char *filename;
    const char *cf;
    char** ds_namv;

    time_t start;
    time_t end;

    unsigned long step;
    unsigned long ds_cnt;

    int status;
    int size;
    int ds;
    int i;
    int timeStamp;

    SEXP out;
    SEXP vec;
    SEXP nam;
    SEXP rowNam;
    SEXP cls;

    filename  = CHAR(asChar(filenameIn));

    if (access(filename, F_OK) == -1) {
	printf("file does not exist\n");
	exit(0);
    }

    cf = CHAR(asChar(cfIn));
    start = (time_t) asInteger(startIn);
    end = (time_t) asInteger(endIn);

    step  = (unsigned long) asInteger(stepIn);



    printf("calling rrdfetch\n");

    status = rrd_fetch_r(filename, cf, &start, &end, &step, &ds_cnt, &ds_namv, &data);
	if (status != 0 || data == NULL) {
	    printf("error running rrd_fetch_r\n");
	    if (data)
		free(data);
	    if (ds_namv) {
		for (int k = 0; k < sizeof(ds_namv)/sizeof(char*); k++) {
		    free(ds_namv[k]);
		}
		free(ds_namv);
	    }
	    exit(0);
	}

    printf("size of data %d start %d end %d step %d ds_cnt %d\n", sizeof(data)/sizeof(rrd_value_t), start, end, step, ds_cnt);

    //turns out rrd_fetch does not include start in data
    size = (end - start)/step - 1;

    out = PROTECT(allocVector(VECSXP, ds_cnt + 1) );

    vec = PROTECT(allocVector(INTSXP, size));
    PROTECT(rowNam = allocVector(STRSXP, size));
    
    //turns out rrd_fetch does not include start in data
    timeStamp = start + step;

    for (i = 0; i < size; i++) {
	INTEGER(vec)[i] = timeStamp;

	timeStamp += step;

    }
    SET_VECTOR_ELT(out, 0, vec);
    setAttrib(out, R_RowNamesSymbol, vec);

    PROTECT(nam = allocVector(STRSXP, ds_cnt + 1));
    SET_STRING_ELT(nam, 0, mkChar("timestamp"));


    for (ds = 0; ds < ds_cnt; ds++){
	SET_STRING_ELT(nam, ds + 1, mkChar(ds_namv[ds]));

	vec = PROTECT(allocVector(REALSXP, size));
	for (i = 0; i < size; i++){
	    /*printf("iterating.. i = %d\n", i);*/
	    REAL(vec)[i] = data[ds + i*ds_cnt];
	}
	SET_VECTOR_ELT(out, ds + 1, vec);
    }

    PROTECT(cls = allocVector(STRSXP, 1)); // class attribute
    SET_STRING_ELT(cls, 0, mkChar("data.frame"));
    classgets(out, cls);
    namesgets(out, nam);




    free(data);
    for (int k = 0; k < sizeof(ds_namv)/sizeof(char*); k++) {
	free(ds_namv[k]);
    }
    free(ds_namv);

    UNPROTECT(ds_cnt + 4);

    return out;


}
Example #7
0
File: Rrd.c Project: oetiker/Rrd
SEXP smartImportRRD(SEXP filenameIn){

    time_t first;
    time_t last;
    time_t start;
    time_t end;

    time_t *startAr;


    unsigned long curStep;
    unsigned long ds_cnt;
    unsigned long step;

    int rraCnt;
    int status;
    int size;
    int i;
    int ds;
    int j;
    int timeStamp;

    char **ds_namv;
    const char *filename;

    rrd_value_t *data;

    rraInfo* rraInfoList;
    rraInfo* rraInfoTmp;

    rrd_info_t *rrdInfo;


    SEXP out;
    SEXP vec;
    SEXP rraSexpList; 
    SEXP rraNames;
    SEXP nam;
    SEXP rowNam;
    SEXP cls;


    filename  = CHAR(asChar(filenameIn));
    if (access(filename, F_OK) == -1) {
	printf("file does not exist\n");
	exit(0);
    }


    printf("calling rrd_last\n");
    last = rrd_last_r(filename);


    printf("calling rrd_info\n");
    rrdInfo = rrd_info_r(filename);

    if (rrdInfo == NULL) {
	printf("getting rrd info failed");
	exit(0);
    }


    printf("calling getrrainfo\n");
    rraInfoList = getRraInfo(rrdInfo, &rraCnt, &step);

    if (rraInfoList == NULL) {
	printf("getting rra info failed\n");
	free(rrdInfo);
	exit(0);

    }
    
    printf("rraCnt %d step %d last %d rraInfoList %p\n", rraCnt, step, last, rraInfoList);
    printRraInfo(rraInfoList);



    startAr = malloc(rraCnt * sizeof(time_t));

    if (startAr == NULL) {
	printf("memory allocation error");
	free(rrdInfo);
	freeRraInfo(rraInfoList);
	exit(0);
    }



    for (i = 0; i < rraCnt; i++) {
	startAr[i] = rrd_first_r(filename, i);
    }
    

    rraInfoTmp = rraInfoList;
    PROTECT(rraNames = allocVector(STRSXP, rraCnt));

    PROTECT(cls = allocVector(STRSXP, 1)); // class attribute
    SET_STRING_ELT(cls, 0, mkChar("data.frame"));


    out = PROTECT(allocVector(VECSXP, rraCnt));

    i = 0;

    printf("entering loop\n");
    while (rraInfoTmp) {

	start = startAr[i];
	end = last;
	curStep = step * rraInfoTmp->perRow;


	status = rrd_fetch_r(filename, rraInfoTmp->cf, &start, &end, &curStep, &ds_cnt, &ds_namv, &data);

	if (status != 0 || data == NULL) {
	    printf("error running rrd_fetch_r\n");
	    free(rrdInfo);
	    freeRraInfo(rraInfoList);
	    free(startAr);
	    if (data)
		free(data);
	    if (ds_namv) {
		for (int k = 0; k < sizeof(ds_namv)/sizeof(char*); k++) {
		    free(ds_namv[k]);
		}
		free(ds_namv);
	    }
	    //TODO unprotect how many times?
	    exit(0);
	}


	printf("size of data %d start %d end %d step %d ds_cnt %d\n", sizeof(data)/sizeof(rrd_value_t), start, end, curStep, ds_cnt);
	fflush(stdout);

	//rrd_fetch does not include start
	size = (end - start)/curStep - 1;
	printf("size %d\n", size);

	rraSexpList = PROTECT(allocVector(VECSXP, ds_cnt + 1));

	vec = PROTECT(allocVector(INTSXP, size));
	PROTECT(rowNam = allocVector(STRSXP, size));
	//rrd_fetch does not include start
	timeStamp = start + curStep;




	for (int j = 0; j < size; j++) {
	    INTEGER(vec)[j] = timeStamp;
	    timeStamp += curStep;

	}

	printf("setting row names\n");
	SET_VECTOR_ELT(rraSexpList, 0, vec);
	setAttrib(rraSexpList, R_RowNamesSymbol, vec);

	PROTECT(nam = allocVector(STRSXP, ds_cnt + 1));
	SET_STRING_ELT(nam, 0, mkChar("timestamp"));


	//TODO stick to row/columns convention
	for (ds = 0; ds < ds_cnt; ds++){
	    SET_STRING_ELT(nam, ds + 1, mkChar(ds_namv[ds]));
	    vec = PROTECT(allocVector(REALSXP, size));

	    for (j = 0; j < size; j++){
		REAL(vec)[j] = data[ds + j*ds_cnt];
	    }



	    printf("adding ds vector to data frame\n");
	    SET_VECTOR_ELT(rraSexpList, ds + 1, vec);
	}

	classgets(rraSexpList, cls);
	namesgets(rraSexpList, nam);



	printf("adding data frame to out\n");
	SET_VECTOR_ELT(out, i, rraSexpList);

	char rraNameString[80];
	char stepString[40];

	sprintf(stepString, "%d", curStep);
	strcpy(rraNameString, rraInfoTmp->cf);
	strcat(rraNameString, stepString);
	SET_STRING_ELT(rraNames, i, mkChar(rraNameString));


	rraInfoTmp = rraInfoTmp->next;

	i++;
	free(data);
    }

    setAttrib(out, R_NamesSymbol, rraNames);


    freeRraInfo(rraInfoList);
    free(startAr);
    free(rrdInfo);
    for (int k = 0; k < sizeof(ds_namv)/sizeof(char*); k++) {
	free(ds_namv[k]);
    }
    free(ds_namv);

    UNPROTECT((ds_cnt + 2)*rraCnt + 3);


    return out;

}
Example #8
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);
}