Product SiteDocumentation Site

3.9. PMAPI Programming Issues and Examples

The following issues and examples are provided to enable you to create better custom performance monitoring tools.
The source code for a sample client (pmclient) using the PMAPI is shipped as part of the PCP package. See the pmclient(1) man page, and the source code, located in ${PCP_DEMOS_DIR}/pmclient.

3.9.1. Symbolic Association between a Metric's Name and Value

A common problem in building specific performance tools is how to maintain the association between a performance metric's name, its access (instantiation) method, and the application program variable that contains the metric's value. Generally this results in code that is easily broken by bug fixes or changes in the underlying data structures. The PMAPI provides a uniform method for instantiating and accessing the values independent of the underlying implementation, although it does not solve the name-variable association problem. However, it does provide a framework within which a manageable solution may be developed.
Fundamentally, the goal is to be able to name a metric and reference the metric's value in a manner that is independent of the order of operations on other metrics; for example, to associate the LOADAV macro with the name kernel.all.load, and then be able to use LOADAV to get at the value of the corresponding metric.
The one-to-one association between the ordinal position of the metric names is input to pmLookupName and the PMIDs returned by this function, and the one-to-one association between the PMIDs input to pmFetch and the values returned by this function provide the basis for an automated solution.
The tool pmgenmap takes the specification of a list of metric names and symbolic tags, in the order they should be passed to pmLookupName and pmFetch. For example, pmclient:
          cat ${PCP_DEMOS_DIR}/pmclient/pmnsmap.spec
pmclient_init {
    hinv.ncpu			NUMCPU
}

pmclient_sample {
    kernel.all.load	LOADAV
    kernel.percpu.cpu.user	CPU_USR
    kernel.percpu.cpu.sys	CPU_SYS
    mem.freemem		FREEMEM
    disk.all.total		DKIOPS
}
This pmgenmap input produces the C code in Example 3.21, “C Code Produced by pmgenmap Input”. It is suitable for including with the #include statement:

Example 3.21. C Code Produced by pmgenmap Input

/*
 * Performance Metrics Name Space Map
 * Built by runme.sh from the file
 * pmnsmap.spec
 * on Thu Jan  9 14:13:49 EST 2014
 *
 * Do not edit this file!
 */

char *pmclient_init[] = {
#define NUMCPU	0
	"hinv.ncpu",

};


char *pmclient_sample[] = {
#define LOADAV	0
	"kernel.all.load",
#define CPU_USR	1
	"kernel.percpu.cpu.user",
#define CPU_SYS	2
	"kernel.percpu.cpu.sys",
#define FREEMEM	3
	"mem.freemem",
#define DKIOPS	4
	"disk.all.total",

};