Product SiteDocumentation Site

2.3.3. Metrics

A PMDA provides support for a collection of metrics. In addition to the obvious performance metrics, and the measures of time, activity and resource utilization, the metrics should also describe how the target domain has been configured, as this can greatly affect the correct interpretation of the observed performance. For example, metrics that describe network transfer rates should also describe the number and type of network interfaces connected to the host (hinv.ninterface, network.interface.speed, network.interface.duplex, and so on)
In addition, the metrics should describe how the PMDA has been configured. For example, if the PMDA was periodically probing a system to measure quality of service, there should be metrics for the delay between probes, the number of probes attempted, plus probe success and failure counters. It may also be appropriate to allow values to be stored (see the pmstore(1) man page) into the delay metric, so that the delay used by the PMDA can be altered dynamically. Data Structures

Each metric must be described in a pmDesc structure; see the pmLookupDesc(3) man page:
typedef struct { 
    pmID        pmid;           /* unique identifier */ 
    int         type;           /* base data type */ 
    pmInDom     indom;          /* instance domain */ 
    int         sem;            /* semantics of value */ 
    pmUnits     units;          /* dimension and units */ 
} pmDesc;
This structure contains the following fields:
A unique identifier, Performance Metric Identifier (PMID), that differentiates this metric from other metrics across the union of all PMDAs
A data type indicator showing whether the format is an integer (32 or 64 bit, signed or unsigned); float; double; string; or arbitrary aggregate of binary data
An instance domain identifier that links this metric to an instance domain
An encoding of the value's semantics (counter, instantaneous, or discrete)
A description of the value's units based on dimension and scale in the three orthogonal dimensions of space, time, and count (or events)


This information can be observed for metrics from any active PMDA using pminfo command line options, for example:
 $ pminfo -d -m network.interface.out.drops

 network.interface.out.drops PMID: 60.3.11
     Data Type: 64-bit unsigned int  InDom: 60.3 0xf000003
     Semantics: counter  Units: count
Symbolic constants of the form PM_TYPE_*, PM_SEM_*, PM_SPACE_*, PM_TIME_*, and PM_COUNT_* are defined in the <pcp/pmapi.h> header file. You may use them to initialize the elements of a pmDesc structure. The pmID type is an unsigned integer that can be safely cast to a __pmID_int structure, which contains fields defining the metric's (PMDA's) domain, cluster, and item number as shown in Example 2.3, “ __pmID_int Structure”:

Example 2.3.  __pmID_int Structure

typedef struct { 
        int             flag:1;
        unsigned int    domain:9;
        unsigned int    cluster:12;
        unsigned int    item:10;
} __pmID_int;
For additional information, see the <pcp/impl.h> file.
The flag field should be ignored. The domain number should be set at run time when the PMDA is initialized. The PMDA_PMID macro defined in <pcp/pmapi.h> can be used to set the cluster and item fields at compile time, as these should always be known and fixed for a particular metric.


The three components of the PMID should correspond exactly to the three-part definition of the PMID for the corresponding metric in the PMNS described in Section 2.4.3, “Name Space”.
A table of pmdaMetric structures should be defined within the PMDA, with one structure per metric as shown in Example 2.4, “ pmdaMetric Structure”.

Example 2.4.  pmdaMetric Structure

typedef struct { 
    void        *m_user;        /* for users external use */ 
    pmDesc      m_desc;         /* metric description */ 
} pmdaMetric;
This structure contains a pmDesc structure and a handle that allows PMDA-specific structures to be associated with each metric. For example, m_user could be a pointer to a global variable containing the metric value, or a pointer to a function that may be called to instantiate the metric's value.
The trivial PMDA, shown in Example 2.5, “Trivial PMDA”, has only a singular metric (that is, no instance domain):

Example 2.5. Trivial PMDA

static pmdaMetric metrictab[] = {
/* time */
 { NULL,
     PMDA_PMUNITS(0, 1, 0, 0, PM_TIME_SEC, 0) }, },
This single metric (trivial.time) has the following:
  • A PMID with a cluster of 0 and an item of 1. Note that this is not yet a complete PMID, the domain number which identifies the PMDA will be combined with it at runtime.
  • An unsigned 32-bit integer (PM_TYPE_U32)
  • A singular value and hence no instance domain (PM_INDOM_NULL)
  • An instantaneous semantic value (PM_SEM_INSTANT)
  • Dimension “time” and the units “seconds”