NAME
pmFetch, pmRequestFetch, pmReceiveFetch - get performance metric values
C SYNOPSIS
#include <pcp/pmapi.h>
int pmFetch(int numpmid, pmID *pmidlist, pmResult **result)
int pmRequestFetch(int cxt, int numpmid, pmID *pmidlist)
int pmReceiveFetch(int cxt, pmResult **result)
cc ... -lpcp
DESCRIPTION
Given a list of Performance Metric IDs (PMID)s, e.g. as constructed by
pmLookupName(3), via pmidlist and numpmid, fetch the values for these
performance metrics.
The call to pmFetch is executed in the context of a source of metrics,
instance profile and collection time, previously established by calls
to the appropriate context and profile functions, namely some of
pmNewContext(3), pmDupContext(3), pmUseContext(3), pmAddProfile(3),
pmDelProfile(3) and pmSetMode(3).
The principal result from pmFetch is returned in the argument result as
a tree, using the following component data structures;
typedef struct {
unsigned int vtype : 8; /* value type (same as pmDesc.type) */
unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */
char vbuf[1]; /* one or more values */
} pmValueBlock;
typedef struct {
int inst; /* instance identifier */
union {
pmValueBlock *pval; /* pointer to value-block */
int lval; /* integer value insitu */
} value;
} pmValue;
typedef struct {
pmID pmid; /* metric identifier */
int numval; /* number of values or error code */
int valfmt; /* value style, insitu or ptr */
pmValue vlist[1]; /* set of instances/values */
} pmValueSet;
/* Result returned by pmFetch() */
typedef struct {
struct timeval timestamp; /* time stamped by collector */
int numpmid; /* number of PMIDs */
pmValueSet *vset[1]; /* set of value sets */
} pmResult;
To accommodate metrics with multiple value instances, the numval field
indicates how many values are returned for each requested PMID. The
field valfmt in the pmValueSet structure indicates if the values for
this metric are stored insitu in the lval field, i.e. a 32-bit integter
quantity (either int, unsigned int, long or unsigned long) or if the
values are held in associated pmValueBlock structures. The
pmValueBlock structure is always used for floating point values (float
or double) and also accommodates arbitrary sized binary data such as
‘string-valued’ metrics and metrics with aggregated or complex data
types. The maximum length of a pmValueBlock buffer is PM_VAL_VLEN_MAX
bytes. If the pmValueBlock format is used, the vtype field indicates
the data type of the value. This field has the same interpretation as
the type field in the pmDesc structure, see pmLookupDesc(3).
Note that the insitu value may be a signed or unsigned 32 bit integer,
signed or unsigned 32 bit long value (on 32 bit platforms), In the
special cases described below, it may also be a 32 bit floating point
value. If the application needs to know the type of an insitu value,
which is almost always the case, it is necessary to fetch the
descriptor for the metric and interpret the type field, as described in
detail in pmLookupDesc(3). When the pmResult is received from a PCP1.x
pmcd, insitu values may also be 32 bit floating point values (of type
PM_TYPE_FLOAT). In all cases, it is good practice to use
pmLookupDesc(3) to fetch the descriptor for the metric and interpret
the type field therein. Note also that the PMAPI(3) will automatically
translate from the PCP2.0 format to the PCP1.x format when a PCP1.x
client requests 32 bit floating point values from a PCP2.0 pmcd, but
the reverse translation does not occur (because the PCP2.0 pmcd cannot
automatically distinguish between arbitrary 32 bit floating point
values and 32 bit integers).
If one value (i.e. associated with a particular instance) for a
requested metric is ‘unavailable’ (at the requested time), then there
is no associated pmValue structure in the result. If there are no
available values for a metric, then numval will be zero and the
associated pmValue[] instance will be empty (valfmt is undefined in
these circumstances, however pmid will be correctly set to the PMID of
the metric with no values).
As an extension of this protocol, if the Performance Metrics Collection
System (PMCS) is able to provide a reason why no values are available
for a particular metric, this is encoded as a standard error code in
the corresponding numval. Since the error codes are all negative,
values for a requested metric are ‘unavailable’ if numval is less than,
or equal to, zero. A performance metric’s value may be ‘unavailable’
for any of the following reasons;
+ The metric is not supported in this version of the software for the
associated Performance Metric Domain
+ Collection is not currently activated in the software for the
associated Performance Metric Domain
+ The associated PMID is not known
+ The current system configuration does not include the associated
hardware component and/or the associated software module, e.g. a
disk is not installed, or off-line, or Oracle is not installed
+ The metric is one for which an instance profile is required, and
none was provided (there are a small number of metrics in this
category, typically ones with very large, and/or very dynamic
instance domains, and/or expensive metric instantiation methods).
In general, we may not be able to differentiate between the various
cases, and if differentiation is not possible, numval will simply be
zero.
The argument definition and the result specifications have been
constructed to ensure that for each PMID in the requested pmidlist
there is exactly one pmValueSet in the result, and further the PMIDs
appear in exactly the same sequence in both pmidlist and result. This
makes the number and order of entries in result completely
deterministic, and greatly simplifies the application programming logic
after the call to pmFetch.
The result structure returned by pmFetch is dynamically allocated using
a combination of malloc(3C) calls and specialized allocation
strategies, and should be released when no longer required by calling
pmFreeResult(3) - under no circumstances should free(3C) be called
directly to release this space.
As common error conditions are encoded in the result data structure,
we’d expect only cataclysmic events to cause an error value to be
returned. One example would be if the metrics source context was a
remote host, and that host or the PMCS on that host became unreachable.
Otherwise the value returned by the pmFetch function will be non-
negative.
If the current context involves fetching metrics from a Performance
Metrics Collector Daemon (PMCD), then the return value may be used to
encode out-of-band changes in the state of the PMCD and the associated
Performance Metrics Daemon Agents (PMDAs), as a bit-wise ‘‘or’’ of the
following values:
PMCD_RESTART_AGENT An attempt has been made to restart at least one
failed PMDA.
PMCD_ADD_AGENT At least one PMDA has been started.
PMCD_DROP_AGENT PMCD has noticed the termination of at least one
PMDA.
The default is to return zero to indicate no change in state, however
the pmResult returned by pmFetch has the same interpretation
independent of the return value being zero or greater than zero.
pmRequestFetch and pmReceiveFetch are used by applications which must
communicate with the PMCD asynchronously. These functions take explict
context handle ctx which must refer to a host context (i.e. created by
passing PM_CONTEXT_HOST to pmNewContext). pmRequestFetch sends a fetch
request to PMCD and returns without waiting for the response,
pmReceiveFetch reads the reply from PMCD. It is the responsibility of
the application to make sure the data are ready before calling
pmReceiveFetch to avoid blocking while reading the reply.
pmReceiveFetch can return a positive value to indicate a change in the
state of PMCD. In this case the result is unchanged and the application
is expected to call pmReceiveResult again.
SEE ALSO
pmcd(1), pmAddProfile(3), PMAPI(3), pmDelProfile(3), pmDupContext(3),
pmExtractValue(3), pmFetchArchive(3), pmFreeResult(3), pmGetInDom(3),
pmLookupDesc(3), pmLookupName(3), pmNewContext(3), pmSetMode(3),
pmUseContext(3) and pmWhichContext(3).
Note that pmFetch is the most primitive method of fetching metric
values from the PMCS. More user friendly interfaces to the PMCS are
available or currently under development - these higher level fetch
methods insulate the user from the intricacies of context creation,
setting up instance profiles, pmResult traversal, and splitting fetches
into batches to minimize PDU traffic or according to other optimization
criteria.
DIAGNOSTICS
As mentioned above, pmFetch returns error codes insitu in the argument
result. If no result is returned, e.g. due to IPC failure using the
current PMAPI context, or end of file on an archive log, then pmFetch
will return a negative error code which may be examined using
pmErrStr(3).
PM_ERR_EOL
When fetching records from an archive log, pmFetch returns this
error code to indicate the end of the log has been passed (or
the start of the log has been passed, if the direction of
traversal is backwards in time). If the ‘‘mode’’ for the
current PMAPI context (see pmSetMode(3)) is PM_MODE_INTERP then
the time origin is advanced, even when this error code is
returned. In this way applications that position the time
outside the range defined by the records in the archive, and
then commence to pmFetch will eventually see valid results once
the time origin moves inside the temporal span of the archive.
PM_ERR_CTXBUSY
Context is currently in use by another asynchronous call.
ENVIRONMENT
Many of the performance metrics exported from PCP agents have the
semantics of counter meaning they are expected to be monotonically
increasing. Under some circumstances, one value of these metrics may
be smaller than the previously fetched value. This can happen when a
counter of finite precision overflows, or when the PCP agent has been
reset or restarted, or when the PCP agent is exporting values from some
underlying instrumentation that is subject to some asynchronous
discontinuity.
The environment variable PCP_COUNTER_WRAP may be set to indicate that
all such cases of a decreasing ‘‘counter’’ should be treated as a
counter overflow, and hence the values are assumed to have wrapped once
in the interval between consecutive samples. This ‘‘wrapping’’
behavior was the default in earlier PCP versions, but by default has
been disabled in PCP version 1.3 and later.