Product SiteDocumentation Site

3.5. Performance Metrics Values

An application may fetch (or store) values for a set of performance metrics, each with a set of associated instances, using a single pmFetch (or pmStore) function call. To accommodate this, values are delivered across the PMAPI in the form of a tree data structure, rooted at a pmResult structure. This encoding is illustrated in Figure 3.1, “A Structured Result for Performance Metrics from pmFetch, and uses the component data structures in Example 3.6, “ pmValueBlock and pmValue Structures”:

Example 3.6.  pmValueBlock and pmValue Structures

typedef struct {
    int inst;                 /* instance identifier */
    union {
        pmValueBlock *pval;   /* pointer to value-block */
        int           lval;   /* integer value insitu */
    } value;
} pmValue;
A Structured Result for Performance Metrics from pmFetch

Figure 3.1. A Structured Result for Performance Metrics from pmFetch

The internal instance identifier is stored in the inst element. If a value for a particular metric-instance pair is a 32-bit integer (signed or unsigned), then it will be stored in the lval element. If not, the value will be in a pmValueBlock structure, as shown in Example 3.7, “pmValueBlock Structure”, and will be located via pval:
The pmValueBlock structure is as follows:

Example 3.7. pmValueBlock Structure

typedef struct {
    unsigned int    vlen : 24;    /* bytes for vtype/vlen + vbuf */
    unsigned int    vtype : 8;    /* value type */
    char            vbuf[1];      /* the value */
} pmValueBlock;
The length of the pmValueBlock (including the vtype and vlen fields) is stored in vlen. Despite the prototype declaration of vbuf, this array really accommodates vlen minus sizeof(vlen) bytes. The vtype field encodes the type of the value in the vbuf[] array, and is one of the PM_TYPE_* macros defined in <pcp/pmapi.h>.
A pmValueSet structure, as shown in Example 3.8, “ pmValueSet Structure”, contains all of the values to be returned from pmFetch for a single performance metric identified by the pmid field.

Example 3.8.  pmValueSet Structure

typedef struct {
    pmID    pmid;          /* metric identifier */
    int     numval;        /* number of values */
    int     valfmt;        /* value style, insitu or ptr */
    pmValue vlist[1];      /* set of instances/values */ 
} pmValueSet;
If positive, the numval field identifies the number of value-instance pairs in the vlist array (despite the prototype declaration of size 1). If numval is zero, there are no values available for the associated performance metric and vlist[0] is undefined. A negative value for numval indicates an error condition (see the pmErrStr(3) man page) and vlist[0] is undefined. The valfmt field has the value PM_VAL_INSITU to indicate that the values for the performance metrics should be located directly via the lval member of the value union embedded in the elements of vlist; otherwise, metric values are located indirectly via the pval member of the elements of vlist.
The pmResult structure, as shown in Example 3.9, “ pmResult Structure”, contains a time stamp and an array of numpmid pointers to pmValueSet.

Example 3.9.  pmResult Structure

/* Result returned by pmFetch() */
typedef struct {
    struct timeval timestamp;    /* stamped by collector */
    int            numpmid;      /* number of PMIDs */
    pmValueSet     *vset[1];     /* set of value sets */
} pmResult
There is one pmValueSet pointer per PMID, with a one-to-one correspondence to the set of requested PMIDs passed to pmFetch.
Along with the metric values, the PMAPI returns a time stamp with each pmResult that serves to identify when the performance metric values were collected. The time is in the format returned by gettimeofday and is typically very close to the time when the metric values were extracted from their respective domains.


There is a question of exactly when individual metrics may have been collected, especially given their origin in potentially different performance metric domains, and variability in metric updating frequency by individual PMDAs. PCP uses a pragmatic approach, in which the PMAPI implementation returns all metrics with values accurate as of the time stamp, to the maximum degree possible, and PMCD demands that all PMDAs deliver values within a small realtime window. The resulting inaccuracy is small, and the additional burden of accurate individual timestamping for each returned metric value is neither warranted nor practical (from an implementation viewpoint).
The PMAPI provides functions to extract, rescale, and print values from the above structures; refer to Section 3.8.11, “PMAPI Ancillary Support Services”.