PMFETCH(3)
π NAME π
pmFetch, pmFetchHighRes, pmHighResFetch β get performance metric values, bestie β¨ (it's a library functions manual situation, iykyk)
πΈ C SYNOPSIS πΈ
#include <pcp/pmapi.h>
int pmFetch(int numpmid, pmID *pmidlist, pmResult **result);
int pmFetchHighRes(int numpmid, pmID *pmidlist, pmHighResResult **result);
cc ... -lpcp
π¦ DESCRIPTION π¦
Okay so picture this: you roll up with a list of Performance Metric Identifiers (PMID)s β like the ones you'd get from pmLookupName(3) β and you hand them over in pmidlist with numpmid telling everyone how many there are. What you get back is the values for those performance metrics. That's the whole vibe. π
Now, important: a call to either pmFetch or pmFetchHighRes doesn't just do whatever it wants. It runs inside the context of a source of metrics, an instance profile, and a collection time β all of which you set up beforehand with the appropriate context and profile functions. Namely some of pmNewContext(3), pmDupContext(3), pmUseContext(3), pmAddProfile(3), pmDelProfile(3) and pmSetMode(3). So like, do your setup first, then fetch. No cap.
The principal result from pmFetch comes back in the argument result as a tree, built out of these 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;
The principal result from pmFetchHighRes is exactly the same when it comes to value sets, but plot twist: you get a higher resolution timestamp β nanosecond instead of microsecond precision β living in the pmHighResResult structure. Obsessed. π
/* Result returned by pmFetchHighRes() */
typedef struct {
struct timespec timestamp; /* time stamped by collector */
int numpmid; /* number of PMIDs */
pmValueSet *vset[1]; /* set of value sets */
} pmHighResResult;
So here's how to read all that. To accommodate metrics with multiple value instances, the numval field tells you how many values came back for each requested PMID. Then the valfmt field in the pmValueSet structure tells you whether the values for this metric are stored insitu in the lval field β i.e. a 32-bit integer quantity (either int, unsigned int, long or unsigned long) β or whether the values are held in associated pmValueBlock structures instead. π«Ά
The pmValueBlock structure is always used for floating point values (float or double), and it also accommodates arbitrary sized binary data β think 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 tells you the data type of the value. That field has the same interpretation as the type field in the pmDesc structure, so go read pmLookupDesc(3).
Lowkey a trap here, so listen up: the insitu value may be a signed or unsigned 32 bit integer, or a signed or unsigned 32 bit long value (on 32 bit platforms). And in the special cases described below, it may also be a 32 bit floating point value. If your application needs to know the type of an insitu value β which, honestly, is almost always the case β then you literally have 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's good practice to use pmLookupDesc(3) to fetch the descriptor for the metric and interpret the type field therein. Also note 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. And if there are no available values at all 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, that reason 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 a number of reasons β the following list is illustrative but not exhaustive: 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).
- If the current context involves fetching metrics from an archive, values may be unavailable in the region around a
<mark>record (seepmlogextract(1)) that indicate a temporal discontinuity in the time-series of metric values.
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, which greatly simplifies your application programming logic after the call to pmFetchHighRes or pmFetch. Slay, honestly. π
The result structure returned by pmFetch is dynamically allocated using a combination of malloc(3) calls and specialized allocation strategies, and it should be released when no longer required by calling pmFreeResult(3). And under no circumstances should free(3) be called directly to release this space.
fr fr, do not callfree(3)on this. UsepmFreeResult(3). That's the rule. π¨
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.
Similarly, the result structure returned by pmFetchHighRes operates under the same principles, and should be released via pmFreeHighResResult(3).
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.PMCD_AGENT_CHANGEβ A convenience macro for any of the three PMDA changes.PMCD_LABEL_CHANGEβ PMCD has been informed of changes to global (context) labels, or new metrics have appeared which have associated labels.PMCD_NAMES_CHANGEβ PMCD has been informed that the namespace has been modified, such that new metrics have appeared or existing metrics have been removed.PMCD_HOSTNAME_CHANGEβ The hostname on the host where PMCD is running has changed. This may be the result of changes from temporary to permanent hostname after a system reboot or some subsequent explicit change to the system's hostname.
The default is to return zero to indicate no change in state, however the pmResult returned by pmFetch (or pmHighResResult returned by pmFetchHighRes) has the same interpretation independent of the return value being zero or greater than zero.
pmHighResFetch is a previous name for pmFetchHighRes that has been maintained for backwards compatibility. π§
π SEE ALSO π
pmcd(1), pmAddProfile(3), PMAPI(3), pmDelProfile(3), pmDupContext(3), pmExtractValue(3), pmFetchArchive(3), pmFreeHighResResult(3), pmFreeResult(3), pmGetInDom(3), pmLookupDesc(3), pmLookupLabels(3), pmLookupName(3), pmNewContext(3), pmSetMode(3), pmUseContext(3) and pmWhichContext(3).
Note that pmFetch and pmFetchHighRes are the most primitive methods of fetching metric values from the PMCS. See the pmFetchGroup(3) API for a higher level method that insulates the user from the intricacies of looking up metric names and metadata, setting up instance profiles, pmResult traversal, conversions, and scaling. π
π DIAGNOSTICS π
ok so remember how we said pmFetch and pmFetchHighRes just drop their error codes right there insitu in the result argument? yeah bestie. that's the whole vibe. but when no result comes back at all β like when IPC fails using the current PMAPI context, or when you hit end of file on an archive β those routines hand you back a negative error code instead, and you go peek at it with pmErrStr(3). π«Ά
here's what those codes are actually saying to you:
PM_ERR_EOLβ when you're fetching records out of an archive,pmFetchthrows this one to say hey, you've passed the end of the archive (or you've passed the start of the archive, if the direction of traversal is backwards in time π). and here's the iconic part: if the "mode" for the current PMAPI context (seepmSetMode(3)) isPM_MODE_INTERP, then the time origin gets advanced β even when this error code is returned. so the way that works is, if your app positions the time outside the range defined by the records in the archive and then starts callingpmFetch, it'll eventually see valid results once the time origin moves inside the temporal span of the archive. slay, it self-heals. β¨-EAGAINβ if the current context involves fetching metrics frompmcd, then a return value of-EAGAINmeans the caller has created too many contexts. that's it. that's the message. go close some, bestie. π
πΈ ENVIRONMENT πΈ
okay so, lore time. many of the performance metrics exported from PCP agents have the semantics of a counter, meaning they're expected to be monotonically increasing. like, always going up, no cap. π
but under some circumstances, one value of these metrics may come back smaller than the previously fetched value. π and that can happen when:
- a counter of finite precision overflows,
- the PCP agent has been reset or restarted,
- or 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. π
β οΈ heads up: this "wrapping" behavior was the default in earlier PCP versions, but by default has been disabled in PCP version 1.3 and later. so don't assume it's on just because it used to be, iykyk. π
and that's the whole page, bestie!! π this one came out of the Performance Co-Pilot (that's PCP π) docs, and it's page PMFETCH(3) in section 3 of the manual. go forth and fetch responsibly. πβ¨π¦
π¦ where this page comes from
- centos-stream 9: pcp-doc 6.3.7-14.el9 Β· GPL-2.0-or-later AND CC-BY-3.0
- debian trixie: libpcp3-dev 6.3.8-1
- ubuntu questing: libpcp3-dev 6.3.8-1
- Copyright (c) 2012-2018,2021 Red Hat
- Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms