Beispiel #1
0
int
QmcEventRecord::setParameter(int index, pmID pmid, QmcContext *context, pmValueSet const *vsp)
{
    QString *name;
    QmcDesc *desc;
    QmcIndom *indom;
    int sts, type;

    if (vsp->numval <= 0)	// no value or an error
	return vsp->numval;

    if ((sts = context->lookup(pmid, &name, &desc, &indom)) < 0)
	return sts;

    QmcEventParameter &parameter = my.parameters[index];
    parameter.setPMID(pmid);
    parameter.setNamePtr(name);
    parameter.setDescPtr(desc);
    parameter.setIndomPtr(indom);
    parameter.setValueCount(vsp->numval);

    type = desc->desc().type;
    for (int i = 0; i < vsp->numval; i++) {
	pmAtomValue result;
	const pmValue *vp = &vsp->vlist[i];
	QmcMetricValue *value = parameter.valuePtr(i);

	sts = PM_ERR_TYPE;	// no nesting events
	if (QmcMetric::real(type) == true) {
	    if ((sts = pmExtractValue(vsp->valfmt, vp,
			    type, &result, PM_TYPE_DOUBLE)) >= 0)
		value->setCurrentValue(result.d);
	} else if (QmcMetric::aggregate(type) == true) {
	    char buffer[32];
	    QmcMetric::aggregateAsString(vp, buffer, sizeof(buffer));
	    value->setStringValue(buffer);
	} else if (QmcMetric::event(type) == false) {
	    if ((sts = pmExtractValue(vsp->valfmt, vp,
			    type, &result, PM_TYPE_STRING)) >= 0) {
		value->setStringValue(result.cp);
		free(result.cp);
	    }
	}
	value->setInstance(vp->inst);
	if (sts < 0)
	    value->setCurrentError(sts);
    }
    return 0;
}
Beispiel #2
0
static unsigned int
get_ncpu(void)
{
    /* there is only one metric in the pmclient_init group */
    pmID	pmidlist[1];
    pmDesc	desclist[1];
    pmResult	*rp;
    pmAtomValue	atom;
    int		sts;

    if ((sts = pmLookupName(1, pmclient_init, pmidlist)) < 0) {
	fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
	fprintf(stderr, "%s: metric \"%s\" not in name space\n",
			pmProgname, pmclient_init[0]);
	exit(1);
    }
    if ((sts = pmLookupDesc(pmidlist[0], desclist)) < 0) {
	fprintf(stderr, "%s: cannot retrieve description for metric \"%s\" (PMID: %s)\nReason: %s\n",
		pmProgname, pmclient_init[0], pmIDStr(pmidlist[0]), pmErrStr(sts));
	exit(1);
    }
    if ((sts = pmFetch(1, pmidlist, &rp)) < 0) {
	fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
	exit(1);
    }

    /* the thing we want is known to be the first value */
    pmExtractValue(rp->vset[0]->valfmt, rp->vset[0]->vlist, desclist[0].type,
		   &atom, PM_TYPE_U32);
    pmFreeResult(rp);

    return atom.ul;
}
Beispiel #3
0
int pcpfastExtractValues(pmResult *rp, int *inst, pmAtomValue *atom, int vsetidx, int vlistidx, int type)
{
    int status;

    *inst = rp->vset[vsetidx]->vlist[vlistidx].inst;
    status = pmExtractValue(rp->vset[vsetidx]->valfmt, &rp->vset[vsetidx]->vlist[vlistidx], type, atom, type);

    return status;
}
Beispiel #4
0
static void
newHashInst(pmValue *vp,
	checkData *checkdata,		/* updated by this function */
	int valfmt,
	struct timeval *timestamp,	/* timestamp for this sample */
	int pos)			/* position of this inst in instlist */
{
    int		sts;
    size_t	size;
    pmAtomValue av;

    if ((sts = pmExtractValue(valfmt, vp, checkdata->desc.type, &av, PM_TYPE_DOUBLE)) < 0) {
	fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
	print_stamp(stderr, timestamp);
	fprintf(stderr, "] ");
	print_metric(stderr, checkdata->desc.pmid);
	fprintf(stderr, ": pmExtractValue failed: %s\n", pmErrStr(sts));
	fprintf(stderr, "%s: possibly corrupt archive?\n", pmProgname);
	exit(EXIT_FAILURE);
    }
    size = (pos+1)*sizeof(instData*);
    checkdata->instlist = (instData**) realloc(checkdata->instlist, size);
    if (!checkdata->instlist)
	__pmNoMem("newHashInst.instlist", size, PM_FATAL_ERR);
    size = sizeof(instData);
    checkdata->instlist[pos] = (instData*) malloc(size);
    if (!checkdata->instlist[pos])
	__pmNoMem("newHashInst.instlist[pos]", size, PM_FATAL_ERR);
    checkdata->instlist[pos]->inst = vp->inst;
    checkdata->instlist[pos]->lastval = av.d;
    checkdata->instlist[pos]->lasttime = *timestamp;
    checkdata->listsize++;
#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL1) {
	char	*name;

	fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
	print_stamp(stderr, timestamp);
	fprintf(stderr, "] ");
	print_metric(stderr, checkdata->desc.pmid);
	if (vp->inst == PM_INDOM_NULL)
	    fprintf(stderr, ": new singular metric\n");
	else {
	    fprintf(stderr, ": new metric-instance pair ");
	    if (pmNameInDom(checkdata->desc.indom, vp->inst, &name) < 0)
		fprintf(stderr, "%d\n", vp->inst);
	    else {
		fprintf(stderr, "\"%s\"\n", name);
		free(name);
	    }
	}

    }
#endif
}
Beispiel #5
0
void
QmcMetric::extractNumericMetric(pmValueSet const *set, pmValue const *value, QmcMetricValue &valueRef)
{
    pmAtomValue result;
    int sts;

    if ((sts = pmExtractValue(set->valfmt, value,
		    desc().desc().type, &result, PM_TYPE_DOUBLE)) >= 0)
	valueRef.setCurrentValue(result.d);
    else
	valueRef.setCurrentError(sts);
}
Beispiel #6
0
/*
** extract values from a pmResult structure using given offset(s)
** "value" is always a macro identifier from a metric map file.
*/
int
extract_integer_index(pmResult *result, pmDesc *descs, int value, int i)
{
	pmAtomValue atom = { 0 };
	pmValueSet *values = result->vset[value];

	if (values->numval <= 0 || values->numval <= i)
		return 0;
	pmExtractValue(values->valfmt, &values->vlist[i],
			descs[value].type, &atom, PM_TYPE_32);
	return atom.l;
}
Beispiel #7
0
/* Print single performance metric rate value */
static void
printrate(int     valfmt,	/* from pmValueSet */
          int     type,		/* from pmDesc */
          pmValue *val1,	/* current value */
          pmValue *val2,	/* previous value */
	  double  delta,	/* time difference between samples */
          int     minwidth)	/* output is at least this wide */
{
    pmAtomValue a, b;
    double	v;
    static int	dowrap = -1;

    pmExtractValue(valfmt, val1, type, &a, PM_TYPE_DOUBLE);
    pmExtractValue(valfmt, val2, type, &b, PM_TYPE_DOUBLE);
    v = a.d - b.d;
    if (v < 0.0) {
	if (dowrap == -1) {
	    /* PCP_COUNTER_WRAP in environment enables "counter wrap" logic */
	    if (getenv("PCP_COUNTER_WRAP") == NULL)
		dowrap = 0;
	    else
		dowrap = 1;
	}
	if (dowrap) {
	    switch (type) {
		case PM_TYPE_32:
		case PM_TYPE_U32:
		    v += (double)UINT_MAX+1;
		    break;
		case PM_TYPE_64:
		case PM_TYPE_U64:
		    v += (double)ULONGLONG_MAX+1;
		    break;
	    }
	}
    }
    v /= delta;
    printreal(v, minwidth);
}
Beispiel #8
0
static __uint64_t
get_value(int metric, pmValue *value)
{
    int sts;
    pmAtomValue val;

    if ((sts = pmExtractValue(valfmt_tab[metric], value,
		  type_tab[metric], &val, PM_TYPE_U64)) < 0) {
	fprintf(stderr, "%s: Failed to extract metric value: %s\n", 
		pmProgname, pmErrStr(sts));
	exit(1);

    }
    return val.ull;
}
Beispiel #9
0
char *
extract_string_index(pmResult *result, pmDesc *descs, int value, char *buffer, int buflen, int i)
{
	pmAtomValue atom = { 0 };
	pmValueSet *values = result->vset[value];

	if (values->numval <= 0 || values->numval <= i)
		return NULL;

	pmExtractValue(values->valfmt, &values->vlist[i],
			descs[value].type, &atom, PM_TYPE_STRING);
	strncpy(buffer, atom.cp, buflen);
	free(atom.cp);
	if (buflen > 1)	/* might be a single character - e.g. process state */
	    buffer[buflen-1] = '\0';
	return buffer;
}
Beispiel #10
0
float
extract_float_inst(pmResult *result, pmDesc *descs, int value, int inst)
{
	pmAtomValue atom = { 0 };
	pmValueSet *values = result->vset[value];
	int i;

	for (i = 0; i < values->numval; i++)
	{
		if (values->vlist[i].inst != inst)
			continue;
		pmExtractValue(values->valfmt, &values->vlist[i],
			descs[value].type, &atom, PM_TYPE_FLOAT);
		break;
	}
	if (values->numval <= 0 || i == values->numval)
		return -1;
	return atom.f;
}
Beispiel #11
0
void
QmcMetric::extractArrayMetric(pmValueSet const *set, pmValue const *vp, QmcMetricValue &valueRef)
{
    pmAtomValue result;
    int sts, type = desc().desc().type;

    if (aggregate(type)) {
	char buffer[32];
	aggregateAsString(vp, buffer, sizeof(buffer));
	valueRef.setStringValue(buffer);
    }
    else if ((sts = pmExtractValue(set->valfmt, vp,
		    type, &result, PM_TYPE_STRING)) >= 0) {
	valueRef.setStringValue(result.cp);
	if (result.cp)
	    free(result.cp);
    }
    else {
	valueRef.setCurrentError(sts);
    }
}
Beispiel #12
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;
}
Beispiel #13
0
/* Print performance metric values */
static void
printvals(Context *x, pmValueSet *vset, int cols)
{
    int 	i, j;
    pmAtomValue	av;
    int		doreal = 0;

    if (x->desc.type == PM_TYPE_FLOAT || x->desc.type == PM_TYPE_DOUBLE)
	doreal = 1;

    /* null instance domain */
    if (x->desc.indom == PM_INDOM_NULL) {
	if (vset->numval == 1) {
	    if (doreal) {
		pmExtractValue(vset->valfmt, &vset->vlist[0], x->desc.type, &av, PM_TYPE_DOUBLE);
		printreal(av.d, cols);
	    }
	    else
		pmPrintValue(stdout, vset->valfmt, x->desc.type, &vset->vlist[0], cols);

	}
	else
	    printf("%*s", cols, "?");
	putchar('\n');
    }

    /* non-null instance domain */
    else {
	for (i = 0; i < x->inum; i++) {
	    for (j = 0; j < vset->numval; j++) {
		if (vset->vlist[j].inst == x->ipairs[i].id)
		    break;
	    }
	    if (j < vset->numval) {
		if (doreal) {
		    pmExtractValue(vset->valfmt, &vset->vlist[j], x->desc.type, &av, PM_TYPE_DOUBLE);
		    printreal(av.d, cols);
		}
		else
		    pmPrintValue(stdout, vset->valfmt, x->desc.type, &vset->vlist[j], cols);
	    }
	    else
		printf("%*s", cols, "?");
	    putchar(' ');
	}
	putchar('\n');

	for (j = 0; j < vset->numval; j++) {
	    for (i = 0; i < x->inum; i++) {
		if (vset->vlist[j].inst == x->ipairs[i].id)
		    break;
	    }
	    if (x->iall == 1 && i == x->inum) {
		printf("Warning: value=");
		if (doreal) {
		    pmExtractValue(vset->valfmt, &vset->vlist[j], x->desc.type, &av, PM_TYPE_DOUBLE);
		    printreal(av.d, 1);
		}
		else
		    pmPrintValue(stdout, vset->valfmt, x->desc.type, &vset->vlist[j], 1);
		printf(", but instance=%d is unknown\n", vset->vlist[j].inst);
	    }
	}
    }
}
Beispiel #14
0
int zbx_module_pcp_fetch_metric(AGENT_REQUEST *request, AGENT_RESULT *result)
{
    int sts;
    char *metric[] = { request->key + strlen(ZBX_PCP_METRIC_PREFIX) };
    char *inst;
    pmID pmid[1];
    pmDesc desc[1];
    pmResult *rp;
    pmAtomValue atom;
    int iid = 0;
    int i;

    /* Parameter is the instance.  */
    switch(request->nparam) {
        case 0:
            inst = NULL;
            break;
        case 1:
            inst = get_rparam(request, 0);
            break;
        default:
            SET_MSG_RESULT(result, strdup("Extraneous instance specification."));
            return SYSINFO_RET_FAIL;
            break;
    }

    /* Preparations and sanity checks.  */
    sts = pmLookupName(1, metric, pmid);
    if (sts < 0) return SYSINFO_RET_FAIL;
    sts = pmLookupDesc(pmid[0], desc);
    if (sts < 0) return SYSINFO_RET_FAIL;
    if (inst != NULL && desc[0].indom == PM_INDOM_NULL) {
        SET_MSG_RESULT(result, strdup("Extraneous instance specification."));
        return SYSINFO_RET_FAIL;
    }
    if ((inst == NULL && desc[0].indom != PM_INDOM_NULL) ||
        (request->nparam == 1 && !strlen(inst))) {
        SET_MSG_RESULT(result, strdup("Missing instance specification."));
        return SYSINFO_RET_FAIL;
    }
    if (desc[0].indom != PM_INDOM_NULL) {
        iid = pmLookupInDom(desc[0].indom, inst);
        if (iid < 0) {
            SET_MSG_RESULT(result, strdup("Instance not available."));
            return SYSINFO_RET_FAIL;
        }
    }

    /* Fetch the metric values.  */
    sts = pmFetch(1, pmid, &rp);
    if (sts < 0) return SYSINFO_RET_FAIL;
    if (rp->vset[0]->numval < 1) {
        pmFreeResult(rp);
        SET_MSG_RESULT(result, strdup("No value available."));
        return SYSINFO_RET_FAIL;
    }

    /* Locate the correct instance.  */
    for (i = 0; desc[0].indom != PM_INDOM_NULL && i < rp->vset[0]->numval; i++) {
        if (rp->vset[0]->vlist[i].inst == iid) {
            break;
        }
    }
    if (i == rp->vset[0]->numval) {
        pmFreeResult(rp);
        return SYSINFO_RET_FAIL;
    }

    /* Extract the wanted value.  */
    sts = pmExtractValue(rp->vset[0]->valfmt, &rp->vset[0]->vlist[i],
                         desc[0].type, &atom, desc[0].type);
    pmFreeResult(rp);
    if (sts < 0) return SYSINFO_RET_FAIL;

    /* Hand it to the caller.  */
    switch(desc[0].type) {
        case PM_TYPE_32:
            SET_UI64_RESULT(result, atom.l);
            break;
        case PM_TYPE_U32:
            SET_UI64_RESULT(result, atom.ul);
            break;
        case PM_TYPE_64:
            SET_UI64_RESULT(result, atom.ll);
            break;
        case PM_TYPE_U64:
            SET_UI64_RESULT(result, atom.ull);
            break;
        case PM_TYPE_FLOAT:
            SET_DBL_RESULT(result, atom.f);
            break;
        case PM_TYPE_DOUBLE:
            SET_DBL_RESULT(result, atom.d);
            break;
        case PM_TYPE_STRING:
            SET_STR_RESULT(result, strdup(atom.cp));
            break;
        default:
            SET_MSG_RESULT(result, strdup("Unsupported metric value type."));
            return SYSINFO_RET_FAIL;
            break;
    }

    /* Success.  */
    return SYSINFO_RET_OK;
}
Beispiel #15
0
static void
docheck(pmResult *result)
{
    int			i, j, k;
    int			sts;
    pmDesc		desc;
    pmAtomValue 	av;
    pmValue		*vp;
    pmValueSet		*vsp;
    __pmHashNode	*hptr = NULL;
    checkData		*checkdata = NULL;
    double		diff;
    struct timeval	timediff;

    for (i = 0; i < result->numpmid; i++) {
	vsp = result->vset[i];

#ifdef PCP_DEBUG
	if (pmDebug & DBG_TRACE_APPL1) {
	    if (vsp->numval == 0) {
		fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
		print_stamp(stderr, &result->timestamp);
		fprintf(stderr, "] ");
		print_metric(stderr, vsp->pmid);
		fprintf(stderr, ": no values returned\n");
		continue;
	    }
	    else if (vsp->numval < 0) {
		fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
		print_stamp(stderr, &result->timestamp);
		fprintf(stderr, "] ");
		print_metric(stderr, vsp->pmid);
		fprintf(stderr, ": error from numval: %s\n", pmErrStr(vsp->numval));
		continue;
	    }
	}
#endif
	if (vsp->numval <= 0)
	    continue;

	/* check if pmid already in hash list */
	if ((hptr = __pmHashSearch(vsp->pmid, &hashlist)) == NULL) {
	    if ((sts = pmLookupDesc(vsp->pmid, &desc)) < 0) {
		fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
		print_stamp(stderr, &result->timestamp);
		fprintf(stderr, "] ");
		print_metric(stderr, vsp->pmid);
		fprintf(stderr, ": pmLookupDesc failed: %s\n", pmErrStr(sts));
		continue;
	    }

	    if (desc.type != PM_TYPE_32 && desc.type != PM_TYPE_U32 &&
		desc.type != PM_TYPE_64 && desc.type != PM_TYPE_U64 &&
		desc.type != PM_TYPE_FLOAT && desc.type != PM_TYPE_DOUBLE) {
		continue;	/* no checks for non-numeric metrics */
	    }

	    /* create a new one & add to list */
	    checkdata = (checkData*) malloc(sizeof(checkData));
	    newHashItem(vsp, &desc, checkdata, &result->timestamp);
	    if (__pmHashAdd(checkdata->desc.pmid, (void*)checkdata, &hashlist) < 0) {
		fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
		print_stamp(stderr, &result->timestamp);
		fprintf(stderr, "] ");
		print_metric(stderr, vsp->pmid);
		fprintf(stderr, ": __pmHashAdd failed (internal pmlogcheck error)\n");
		/* free memory allocated above on insert failure */
		for (j = 0; j < vsp->numval; j++) {
		    if (checkdata->instlist[j] != NULL)
			free(checkdata->instlist[j]);
		}
		if (checkdata->instlist != NULL)
		    free(checkdata->instlist);
		continue;
	    }
	}
	else {	/* pmid exists - update statistics */
	    checkdata = (checkData *)hptr->data;
	    for (j = 0; j < vsp->numval; j++) {	/* iterate thro result values */
		vp = &vsp->vlist[j];
		k = j;	/* index into stored inst list, result may differ */
		if ((vsp->numval > 1) || (checkdata->desc.indom != PM_INDOM_NULL)) {
		    /* must store values using correct inst - probably in correct order already */
		    if ((k < checkdata->listsize) && (checkdata->instlist[k]->inst != vp->inst)) {
			for (k = 0; k < checkdata->listsize; k++) {
			    if (vp->inst == checkdata->instlist[k]->inst) {
				break;	/* k now correct */
			    }
			}
			if (k == checkdata->listsize) {	/* no matching inst was found */
			    newHashInst(vp, checkdata, vsp->valfmt, &result->timestamp, k);
			    continue;
			}
		    }
		    else if (k >= checkdata->listsize) {
			k = checkdata->listsize;
			newHashInst(vp, checkdata, vsp->valfmt, &result->timestamp, k);
			continue;
		    }
		}
		if (k >= checkdata->listsize) {	/* only error values observed so far */
		    k = checkdata->listsize;
		    newHashInst(vp, checkdata, vsp->valfmt, &result->timestamp, k);
		    continue;
		}

		timediff = result->timestamp;
		tsub(&timediff, &(checkdata->instlist[k]->lasttime));
		if (timediff.tv_sec < 0) {
		    /* clip negative values at zero */
		    timediff.tv_sec = 0;
		    timediff.tv_usec = 0;
		}
		diff = __pmtimevalToReal(&timediff);
		if ((sts = pmExtractValue(vsp->valfmt, vp, checkdata->desc.type, &av, PM_TYPE_DOUBLE)) < 0) {
		    fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
		    print_stamp(stderr, &result->timestamp);
		    fprintf(stderr, "] ");
		    print_metric(stderr, vsp->pmid);
		    fprintf(stderr, ": pmExtractValue failed: %s\n", pmErrStr(sts));
		    continue;
		}
		if (checkdata->desc.sem == PM_SEM_COUNTER) {
		    if (diff == 0.0) continue;
		    diff *= checkdata->scale;
#ifdef PCP_DEBUG
		    if (pmDebug & DBG_TRACE_APPL2) {
			fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol);
			print_stamp(stderr, &result->timestamp);
			fprintf(stderr, "] ");
			print_metric(stderr, checkdata->desc.pmid);
			fprintf(stderr, ": current counter value is %.0f\n", av.d);
		    }
#endif
		    unwrap(av.d, &(result->timestamp), checkdata, k);
		}
		checkdata->instlist[k]->lastval = av.d;
		checkdata->instlist[k]->lasttime = result->timestamp;
	    }
	}
    }
}
Beispiel #16
0
static int
papi_store(pmResult *result, pmdaExt *pmda)
{
    int sts = 0;
    int sts2 = 0;
    int i, j;
    const char *delim = " ,";
    char *substring;

    if (!permission_check(pmda->e_context))
	return PM_ERR_PERMISSION;
    for (i = 0; i < result->numpmid; i++) {
	pmValueSet *vsp = result->vset[i];
	__pmID_int *idp = (__pmID_int *)&(vsp->pmid);
	pmAtomValue av;

	if (idp->cluster != CLUSTER_CONTROL) {
	    sts2 = PM_ERR_PERMISSION;
	    continue;
	}
	switch (idp->item) {
	case CONTROL_ENABLE:
	case CONTROL_DISABLE: // NB: almost identical handling!
	    if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
				      PM_TYPE_STRING, &av, PM_TYPE_STRING)) < 0) {
		sts2 = sts;
		continue;
	    }
	    substring = strtok(av.cp, delim);
	    while (substring != NULL) {
		for (j = 0; j < number_of_events; j++) {
		    if (!strcmp(substring, papi_info[j].papi_string_code)) {
			papi_info[j].metric_enabled =
			    (idp->item == CONTROL_ENABLE) ? METRIC_ENABLED_FOREVER : 0;
			break;
		    }
		}
		if (j == number_of_events) {
		    if (pmDebug & DBG_TRACE_APPL0)
			__pmNotifyErr(LOG_DEBUG, "metric name %s does not match any known metrics\n", substring);
		    sts = 1;
		    /* NB: continue for other event names that may succeed */
		}
		substring = strtok(NULL, delim);
	    }
	    if (sts) { /* any unknown metric name encountered? */
		sts = refresh_metrics(0); /* still enable those that we can */
		if (sts == 0)
		    sts = PM_ERR_BADSTORE; /* but return overall error */
	    } else {
		sts = refresh_metrics(0);
	    }
            // NB: We could iterate the affected papi_info[j]'s again to see which
            // counters were successfully activated (position >= 0).  Then again,
            // the user will find out soon enough, when attempting to fetch them.
	    sts2 = sts;
	    continue;

	case CONTROL_RESET:
	    for (j = 0; j < number_of_events; j++)
		papi_info[j].metric_enabled = 0;
	    sts = refresh_metrics(0);
	    continue;

	case CONTROL_AUTO_ENABLE:
	    if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
				      PM_TYPE_U32, &av, PM_TYPE_U32)) < 0) {
		sts2 = sts;
		continue;
	    }
	    auto_enable_time = av.ul;
	    sts = papi_setup_auto_af();
	    sts2 = sts;
	    continue;

	case CONTROL_MULTIPLEX:
	    if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
				      PM_TYPE_U32, &av, PM_TYPE_U32)) < 0) {
		sts2 = sts;
		continue;
	    }
	    enable_multiplexing = av.ul;
	    sts = refresh_metrics(0);
	    sts2 = sts;
	    continue;

	default:
	    sts2 = PM_ERR_PMID;
	    continue;
	}
    }
    if (sts == 0)
	sts = sts2;
    return sts;
}