Esempio n. 1
0
/* Convert the time scale but not the value nor the dimensionality. */
int convert_time_scale(void)
{
    pmAtomValue ival;
    pmAtomValue oval;

    pmUnits iunits = PMDA_PMUNITS(1, -1, 0, PM_SPACE_KBYTE, PM_TIME_SEC, 0);
    pmUnits ounits = PMDA_PMUNITS(1, -1, 0, PM_SPACE_KBYTE, PM_TIME_NSEC, 0);

    ival.l = oval.l = 100;

    return(pmConvScale(PM_TYPE_32, &ival, &iunits, &oval, &ounits));
}
Esempio n. 2
0
void
SamplingItem::rescaleValues(pmUnits *new_units)
{
    pmUnits	*old_units = &ChartItem::my.units;
    pmAtomValue	old_av, new_av;

    console->post("Chart::update change units from %s to %s",
			pmUnitsStr(old_units), pmUnitsStr(new_units));

    for (int i = my.dataCount - 1; i >= 0; i--) {
	if (my.data[i] != qQNaN()) {
	    old_av.d = my.data[i];
	    pmConvScale(PM_TYPE_DOUBLE, &old_av, old_units, &new_av, new_units);
	    my.data[i] = new_av.d;
	}
	if (my.itemData[i] != qQNaN()) {
	    old_av.d = my.itemData[i];
	    pmConvScale(PM_TYPE_DOUBLE, &old_av, old_units, &new_av, new_units);
	    my.itemData[i] = new_av.d;
	}
    }
}
Esempio n. 3
0
void
SamplingItem::updateValues(bool forward,
		bool rateConvert, pmUnits *units, int sampleHistory, int,
		double, double, double)
{
    pmAtomValue	scaled, raw;
    QmcMetric	*metric = ChartItem::my.metric;
    double	value;
    int		sz;

    if (metric->numValues() < 1 || metric->error(0)) {
	value = qQNaN();
    } else {
	// convert raw value to current chart scale
	raw.d = rateConvert ? metric->value(0) : metric->currentValue(0);
	pmConvScale(PM_TYPE_DOUBLE, &raw, &ChartItem::my.units, &scaled, units);
	value = scaled.d * my.scale;
    }

    if (my.dataCount < sampleHistory)
	sz = qMax(0, (int)(my.dataCount * sizeof(double)));
    else
	sz = qMax(0, (int)((my.dataCount - 1) * sizeof(double)));

    if (forward) {
	memmove(&my.data[1], &my.data[0], sz);
	memmove(&my.itemData[1], &my.itemData[0], sz);
	my.data[0] = value;
    } else {
	memmove(&my.data[0], &my.data[1], sz);
	memmove(&my.itemData[0], &my.itemData[1], sz);
	my.data[my.dataCount - 1] = value;
    }

    if (my.dataCount < sampleHistory)
	my.dataCount++;
}
Esempio n. 4
0
static void
get_sample(info_t *ip)
{
    static pmResult	*crp = NULL;	/* current */
    static pmResult	*prp = NULL;	/* prior */
    static int		first = 1;
    static int		numpmid;
    static pmID		*pmidlist;
    static pmDesc	*desclist;
    static int		inst1;
    static int		inst15;
    static pmUnits	mbyte_scale;

    int			sts;
    int			i;
    float		u;
    pmAtomValue		tmp;
    pmAtomValue		atom;
    double		dt;

    if (first) {
	/* first time initialization */
	mbyte_scale.dimSpace = 1;
	mbyte_scale.scaleSpace = PM_SPACE_MBYTE;

	numpmid = sizeof(pmclient_sample) / sizeof(char *);
	if ((pmidlist = (pmID *)malloc(numpmid * sizeof(pmidlist[0]))) == NULL) {
	    fprintf(stderr, "%s: get_sample: malloc: %s\n", pmProgname, osstrerror());
	    exit(1);
	}
	if ((desclist = (pmDesc *)malloc(numpmid * sizeof(desclist[0]))) == NULL) {
	    fprintf(stderr, "%s: get_sample: malloc: %s\n", pmProgname, osstrerror());
	    exit(1);
	}
	if ((sts = pmLookupName(numpmid, pmclient_sample, pmidlist)) < 0) {
	    printf("%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
	    for (i = 0; i < numpmid; i++) {
		if (pmidlist[i] == PM_ID_NULL)
		    fprintf(stderr, "%s: metric \"%s\" not in name space\n", pmProgname, pmclient_sample[i]);
	    }
	    exit(1);
	}
	for (i = 0; i < numpmid; i++) {
	    if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) {
		fprintf(stderr, "%s: cannot retrieve description for metric \"%s\" (PMID: %s)\nReason: %s\n",
		    pmProgname, pmclient_sample[i], pmIDStr(pmidlist[i]), pmErrStr(sts));
		exit(1);
	    }
	}
    }

    /* fetch the current metrics */
    if ((sts = pmFetch(numpmid, pmidlist, &crp)) < 0) {
	fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
	exit(1);
    }

    /*
     * minor gotcha ... for archives, it helps to do the first fetch of
     * real data before interrogating the instance domains ... this
     * forces us to be "after" the first batch of instance domain info
     * in the meta data files
     */
    if (first) {
	/*
	 * from now on, just want the 1 minute and 15 minute load averages,
	 * so limit the instance profile for this metric
	 */
	pmDelProfile(desclist[LOADAV].indom, 0, NULL);	/* all off */
	if ((inst1 = pmLookupInDom(desclist[LOADAV].indom, "1 minute")) < 0) {
	    fprintf(stderr, "%s: cannot translate instance for 1 minute load average\n", pmProgname);
	    exit(1);
	}
	pmAddProfile(desclist[LOADAV].indom, 1, &inst1);
	if ((inst15 = pmLookupInDom(desclist[LOADAV].indom, "15 minute")) < 0) {
	    fprintf(stderr, "%s: cannot translate instance for 15 minute load average\n", pmProgname);
	    exit(1);
	}
	pmAddProfile(desclist[LOADAV].indom, 1, &inst15);

	first = 0;
    }

    /* if the second or later sample, pick the results apart */
    if (prp !=  NULL) {
	
	dt = __pmtimevalSub(&crp->timestamp, &prp->timestamp);
	ip->cpu_util = 0;
	ip->peak_cpu_util = -1;	/* force re-assignment at first CPU */
	for (i = 0; i < ncpu; i++) {
	    pmExtractValue(crp->vset[CPU_USR]->valfmt,
			   &crp->vset[CPU_USR]->vlist[i],
			   desclist[CPU_USR].type, &atom, PM_TYPE_FLOAT);
	    u = atom.f;
	    pmExtractValue(prp->vset[CPU_USR]->valfmt,
			   &prp->vset[CPU_USR]->vlist[i],
			   desclist[CPU_USR].type, &atom, PM_TYPE_FLOAT);
	    u -= atom.f;
	    pmExtractValue(crp->vset[CPU_SYS]->valfmt,
			   &crp->vset[CPU_SYS]->vlist[i],
			   desclist[CPU_SYS].type, &atom, PM_TYPE_FLOAT);
	    u += atom.f;
	    pmExtractValue(prp->vset[CPU_SYS]->valfmt,
			   &prp->vset[CPU_SYS]->vlist[i],
			   desclist[CPU_SYS].type, &atom, PM_TYPE_FLOAT);
	    u -= atom.f;
	    /*
	     * really should use pmConvertValue, but I _know_ the times
	     * are in msec!
	     */
	    u = u / (1000 * dt);

	    if (u > 1.0)
		/* small errors are possible, so clip the utilization at 1.0 */
		u = 1.0;
	    ip->cpu_util += u;
	    if (u > ip->peak_cpu_util) {
		ip->peak_cpu_util = u;
		ip->peak_cpu = i;
	    }
	}
	ip->cpu_util /= ncpu;

	/* freemem - expect just one value */
	pmExtractValue(crp->vset[FREEMEM]->valfmt, crp->vset[FREEMEM]->vlist,
		    desclist[FREEMEM].type, &tmp, PM_TYPE_FLOAT);
	/* convert from today's units at the collection site to Mbytes */
	pmConvScale(PM_TYPE_FLOAT, &tmp, &desclist[FREEMEM].units,
		    &atom, &mbyte_scale);
	ip->freemem = atom.f;

	/* disk IOPS - expect just one value, but need delta */
	pmExtractValue(crp->vset[DKIOPS]->valfmt, crp->vset[DKIOPS]->vlist,
		    desclist[DKIOPS].type, &atom, PM_TYPE_U32);
	ip->dkiops = atom.ul;
	pmExtractValue(prp->vset[DKIOPS]->valfmt, prp->vset[DKIOPS]->vlist,
		    desclist[DKIOPS].type, &atom, PM_TYPE_U32);
	ip->dkiops -= atom.ul;
	ip->dkiops = ((float)(ip->dkiops) + 0.5) / dt;

	/* load average ... process all values, matching up the instances */
	for (i = 0; i < crp->vset[LOADAV]->numval; i++) {
	    pmExtractValue(crp->vset[LOADAV]->valfmt,
			   &crp->vset[LOADAV]->vlist[i],
			   desclist[LOADAV].type, &atom, PM_TYPE_FLOAT);
	    if (crp->vset[LOADAV]->vlist[i].inst == inst1)
		ip->load1 = atom.f;
	    else if (crp->vset[LOADAV]->vlist[i].inst == inst15)
		ip->load15 = atom.f;
	}

	/* free very old result */
	pmFreeResult(prp);
    }
    ip->timestamp = crp->timestamp;

    /* swizzle result pointers */
    prp = crp;
}
Esempio n. 5
0
int
QmcMetric::update()
{
    uint i, err = 0;
    uint num = numValues();
    int sts;
    pmAtomValue ival, oval;
    double delta = context()->timeDelta();
    static int wrap = -1;

    if (num == 0 || my.status < 0)
	return my.status;

    // PCP_COUNTER_WRAP in environment enables "counter wrap" logic
    if (wrap == -1)
	wrap = (getenv("PCP_COUNTER_WRAP") != NULL);

    for (i = 0; i < num; i++) {
	my.values[i].setError(my.values[i].currentError());
	if (my.values[i].error() < 0)
	    err++;
	if (pmDebug & DBG_TRACE_VALUE) {
	    QTextStream cerr(stderr);
	    if (my.values[i].error() < 0)
		cerr << "QmcMetric::update: " << spec(true, true, i) 
		     << ": " << pmErrStr(my.values[i].error()) << endl;
	}
    }

    if (!real())
	return err;

    if (desc().desc().sem == PM_SEM_COUNTER) {
	for (i = 0; i < num; i++) {
	    QmcMetricValue& value = my.values[i];

	    if (value.error() < 0) {		// we already know we
		value.setValue(0.0);		// don't have this value
		continue;
	    }
	    if (value.previousError() < 0) {	// we need two values
		value.setValue(0.0);		// for a rate
		value.setError(value.previousError());
		err++;
		if (pmDebug & DBG_TRACE_VALUE) {
		    QTextStream cerr(stderr);
		    cerr << "QmcMetric::update: Previous: " 
			 << spec(true, true, i) << ": "
			 << pmErrStr(value.error()) << endl;
		}
		continue;
	    }

	    value.setValue(value.currentValue() - value.previousValue());

	    // wrapped going forwards
	    if (value.value() < 0 && delta > 0) {
		if (wrap) {
		    switch(desc().desc().type) {
		    case PM_TYPE_32:
		    case PM_TYPE_U32:
			value.addValue((double)UINT_MAX+1);
			break;
		    case PM_TYPE_64:
		    case PM_TYPE_U64:
			value.addValue((double)ULONGLONG_MAX+1);
			break;
		    }
		}
		else {			// counter not monotonic
		    value.setValue(0.0);	// increasing
		    value.setError(PM_ERR_VALUE);
		    err++;
		    continue;
		}
	    }
	    // wrapped going backwards
	    else if (value.value() > 0 && delta < 0) {
		if (wrap) {
		    switch(desc().desc().type) {
		    case PM_TYPE_32:
		    case PM_TYPE_U32:
			value.subValue((double)UINT_MAX+1);
			break;
		    case PM_TYPE_64:
		    case PM_TYPE_U64:
			value.subValue((double)ULONGLONG_MAX+1);
			break;
		    }
		}
		else {			// counter not monotonic
		    value.setValue(0.0);	// increasing
		    value.setError(PM_ERR_VALUE);
		    err++;
		    continue;
		}
	    }

	    if (delta != 0)			// sign of delta and v
		value.divValue(delta);		// should be the same
	    else
		value.setValue(0.0);		// nothing can have happened
	}
    }
    else {
	for (i = 0; i < num; i++) {
	    QmcMetricValue& value = my.values[i];
	    if (value.error() < 0)
		value.setValue(0.0);
	    else
		value.setValue(value.currentValue());
	}
    }

    if (my.scale != 0.0) {
	for (i = 0; i < num; i++) {
	    if (my.values[i].error() >= 0)
		my.values[i].divValue(my.scale);
	}
    }

    if (desc().useScaleUnits()) {
	for (i = 0; i < num; i++) {
	    if (my.values[i].error() < 0)
		continue;
	    ival.d = my.values[i].value();
	    pmUnits units = desc().desc().units;
	    sts = pmConvScale(PM_TYPE_DOUBLE, &ival, &units,
			      &oval, (pmUnits *)&(desc().scaleUnits()));
	    if (sts < 0)
		my.values[i].setError(sts);
	    else {
		my.values[i].setValue(oval.d);
		if (pmDebug & DBG_TRACE_VALUE) {
		    QTextStream cerr(stderr);
		    cerr << "QmcMetric::update: scaled " << my.name
			 << " from " << ival.d << " to " << oval.d
			 << endl;
		}
	    }
	}
    }

    return err;
}
Esempio n. 6
0
int
main(int argc, char **argv)
{
    int		c;
    int		sts;
    int		errflag = 0;
    static char	*usage = "[-D debug] type value iunit ounit\n"
"\n"
"iunit and ounit are in the 6-integer format:\n"
"dimspace:dimtime:dimcount:scalespace:scaletime:scalecount\n";
    pmUnits	iu;
    pmUnits	ou;
    int		type;
    int		vbase;
    pmAtomValue	iv;
    pmAtomValue	ov;
    char	*vp;
    char	*q;

    __pmSetProgname(argv[0]);

    /* stop at type arg, so value may have leading "-" */
    putenv("POSIXLY_CORRECT=yes");

    while ((c = getopt(argc, argv, "D:")) != EOF) {
	switch (c) {

	case 'D':	/* debug flag */
	    sts = __pmParseDebug(optarg);
	    if (sts < 0) {
		fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
		    pmProgname, optarg);
		errflag++;
	    }
	    else
		pmDebug |= sts;
	    break;

	case '?':
	default:
	    errflag++;
	    break;
	}
    }

    if (errflag || argc - optind != 4) {
	fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
	exit(1);
    }



    /* non-flag args are argv[optind] ... argv[argc-1] */
    type = atoi(argv[optind]);
    optind++;

    if (strncmp(argv[optind], "0x", 2) == 0) {
	vp = &argv[optind][2];
	vbase = 16;
    }
    else {
	vp = argv[optind];
	vbase = 10;
    }

    q = vp;
    switch (type) {
	case PM_TYPE_32:
	    iv.l = strtol(vp, &q, vbase);
	    break;
	case PM_TYPE_U32:
	    iv.ul = strtoul(vp, &q, vbase);
	    break;
	case PM_TYPE_64:
	    iv.ll = strtoll(vp, &q, vbase);
	    break;
	case PM_TYPE_U64:
	    iv.ull = strtoull(vp, &q, vbase);
	    break;
	case PM_TYPE_FLOAT:
	    sts = sscanf(vp, "%f", &iv.f);
	    if (sts == 1) q = "";
	    break;
	case PM_TYPE_DOUBLE:
	    sts = sscanf(vp, "%lf", &iv.d);
	    if (sts == 1) q = "";
	    break;
	default:
	case PM_TYPE_STRING:
	    iv.cp = vp;
	    q = "";
	    break;
	case PM_TYPE_AGGREGATE:
	case PM_TYPE_AGGREGATE_STATIC:
	    iv.vbp = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE+strlen(vp));
	    iv.vbp->vlen = PM_VAL_HDR_SIZE+strlen(vp);
	    iv.vbp->vtype = type;
	    strncpy(iv.vbp->vbuf, vp, strlen(vp));
	    q = "";
	    break;
	case PM_TYPE_EVENT:	// ignore the value, force 0 event records
	    iv.vbp = (pmValueBlock *)malloc(sizeof(pmEventArray)-sizeof(pmEventRecord));
	    iv.vbp->vlen = sizeof(pmEventArray)-sizeof(pmEventRecord);
	    iv.vbp->vtype = type;
	    memset((void *)iv.vbp->vbuf, 0, sizeof(int));
	    q = "";
	    break;
	case PM_TYPE_HIGHRES_EVENT:	// ignore the value, force 0 event records
	    iv.vbp = (pmValueBlock *)malloc(sizeof(pmHighResEventArray)-sizeof(pmHighResEventRecord));
	    iv.vbp->vlen = sizeof(pmHighResEventArray)-sizeof(pmHighResEventRecord);
	    iv.vbp->vtype = type;
	    memset((void *)iv.vbp->vbuf, 0, sizeof(int));
	    q = "";
	    break;
    }
    optind++;

    if (*q != '\0') {
	fprintf(stderr, "Value botched @ %s\n", q);
	exit(1);
    }

    vp = argv[optind];
    iu.dimSpace = strtol(vp, &q, 10);
    if (*q != ':') goto bad_in;
    vp = ++q;
    iu.dimTime = strtol(vp, &q, 10);
    if (*q != ':') goto bad_in;
    vp = ++q;
    iu.dimCount = strtol(vp, &q, 10);
    if (*q != ':') goto bad_in;
    vp = ++q;
    iu.scaleSpace = strtol(vp, &q, 10);
    if (*q != ':') goto bad_in;
	vp = ++q;
    iu.scaleTime = strtol(vp, &q, 10);
    if (*q != ':') goto bad_in;
	vp = ++q;
    iu.scaleCount = strtol(vp, &q, 10);
    if (*q != '\0') goto bad_in;
    optind++;

    vp = argv[optind];
    ou.dimSpace = strtol(vp, &q, 10);
    if (*q != ':') goto bad_out;
    vp = ++q;
    ou.dimTime = strtol(vp, &q, 10);
    if (*q != ':') goto bad_out;
    vp = ++q;
    ou.dimCount = strtol(vp, &q, 10);
    if (*q != ':') goto bad_out;
    vp = ++q;
    ou.scaleSpace = strtol(vp, &q, 10);
    if (*q != ':') goto bad_out;
	vp = ++q;
    ou.scaleTime = strtol(vp, &q, 10);
    if (*q != ':') goto bad_out;
	vp = ++q;
    ou.scaleCount = strtol(vp, &q, 10);
    if (*q != '\0') goto bad_out;

    printf("type=%d input units=%s value=%s\n", type, pmUnitsStr(&iu), pmAtomStr(&iv, type));

    if ((sts = pmConvScale(type, &iv, &iu, &ov, &ou)) < 0)
	printf("pmConvScale Error: %s\n", pmErrStr(sts));
    else
	printf("output units=%s value=%s\n", pmUnitsStr(&ou), pmAtomStr(&ov, type));

    exit(0);

bad_in:
    fprintf(stderr, "Input units botch @ %s\n", q);
    exit(1);

bad_out:
    fprintf(stderr, "Output units botch @ %s\n", q);
    exit(1);
}