diff options
Diffstat (limited to 'src/include/pcp/pmapi.h')
-rw-r--r-- | src/include/pcp/pmapi.h | 884 |
1 files changed, 884 insertions, 0 deletions
diff --git a/src/include/pcp/pmapi.h b/src/include/pcp/pmapi.h new file mode 100644 index 0000000..be4b45e --- /dev/null +++ b/src/include/pcp/pmapi.h @@ -0,0 +1,884 @@ +/* + * Copyright (c) 2012-2014 Red Hat. + * Copyright (c) 1997,2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PMAPI_H +#define _PMAPI_H + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> + +/* + * Platform and environment customization + */ +#include "platform_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PMAPI_VERSION_2 2 +#define PMAPI_VERSION PMAPI_VERSION_2 + +/* + * -------- Naming Services -------- + */ +typedef unsigned int pmID; /* Metric Identifier */ +#define PM_ID_NULL 0xffffffff + +typedef unsigned int pmInDom; /* Instance-Domain */ +#define PM_INDOM_NULL 0xffffffff +#define PM_IN_NULL 0xffffffff + +#define PM_NS_DEFAULT NULL /* default name */ + +/* + * Encoding for the units (dimensions Time and Space) and scale + * for Performance Metric Values + * + * For example, a pmUnits struct of + * { 1, -1, 0, PM_SPACE_MBYTE, PM_TIME_SEC, 0 } + * represents Mbytes/sec, while + * { 0, 1, -1, 0, PM_TIME_HOUR, 6 } + * represents hours/million-events + */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + signed int dimSpace : 4; /* space dimension */ + signed int dimTime : 4; /* time dimension */ + signed int dimCount : 4; /* event dimension */ + unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */ + unsigned int scaleTime : 4; /* one of PM_TIME_* below */ + signed int scaleCount : 4; /* one of PM_COUNT_* below */ + unsigned int pad : 8; +#else + unsigned int pad : 8; + signed int scaleCount : 4; /* one of PM_COUNT_* below */ + unsigned int scaleTime : 4; /* one of PM_TIME_* below */ + unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */ + signed int dimCount : 4; /* event dimension */ + signed int dimTime : 4; /* time dimension */ + signed int dimSpace : 4; /* space dimension */ +#endif +} pmUnits; /* dimensional units and scale of value */ + +/* pmUnits.scaleSpace */ +#define PM_SPACE_BYTE 0 /* bytes */ +#define PM_SPACE_KBYTE 1 /* Kilobytes (1024) */ +#define PM_SPACE_MBYTE 2 /* Megabytes (1024^2) */ +#define PM_SPACE_GBYTE 3 /* Gigabytes (1024^3) */ +#define PM_SPACE_TBYTE 4 /* Terabytes (1024^4) */ +#define PM_SPACE_PBYTE 5 /* Petabytes (1024^5) */ +#define PM_SPACE_EBYTE 6 /* Exabytes (1024^6) */ +/* pmUnits.scaleTime */ +#define PM_TIME_NSEC 0 /* nanoseconds */ +#define PM_TIME_USEC 1 /* microseconds */ +#define PM_TIME_MSEC 2 /* milliseconds */ +#define PM_TIME_SEC 3 /* seconds */ +#define PM_TIME_MIN 4 /* minutes */ +#define PM_TIME_HOUR 5 /* hours */ +/* + * pmUnits.scaleCount (e.g. count events, syscalls, interrupts, etc.) + * -- these are simply powers of 10, and not enumerated here, + * e.g. 6 for 10^6, or -3 for 10^-3 + */ +#define PM_COUNT_ONE 0 /* 1 */ + +/* Performance Metric Descriptor */ +typedef struct { + pmID pmid; /* unique identifier */ + int type; /* base data type (see below) */ + pmInDom indom; /* instance domain */ + int sem; /* semantics of value (see below) */ + pmUnits units; /* dimension and units */ +} pmDesc; + +/* pmDesc.type -- data type of metric values */ +#define PM_TYPE_NOSUPPORT -1 /* not implemented in this version */ +#define PM_TYPE_32 0 /* 32-bit signed integer */ +#define PM_TYPE_U32 1 /* 32-bit unsigned integer */ +#define PM_TYPE_64 2 /* 64-bit signed integer */ +#define PM_TYPE_U64 3 /* 64-bit unsigned integer */ +#define PM_TYPE_FLOAT 4 /* 32-bit floating point */ +#define PM_TYPE_DOUBLE 5 /* 64-bit floating point */ +#define PM_TYPE_STRING 6 /* array of char */ +#define PM_TYPE_AGGREGATE 7 /* arbitrary binary data (aggregate) */ +#define PM_TYPE_AGGREGATE_STATIC 8 /* static pointer to aggregate */ +#define PM_TYPE_EVENT 9 /* packed pmEventArray */ +#define PM_TYPE_HIGHRES_EVENT 10 /* packed pmHighResEventArray */ +#define PM_TYPE_UNKNOWN 255 /* used in pmValueBlock, not pmDesc */ + +/* pmDesc.sem -- semantics/interpretation of metric values */ +#define PM_SEM_COUNTER 1 /* cumulative counter (monotonic increasing) */ + /* was PM_SEM_RATE, no longer used now */ +#define PM_SEM_INSTANT 3 /* instantaneous value, continuous domain */ +#define PM_SEM_DISCRETE 4 /* instantaneous value, discrete domain */ + +#define PM_ERR_BASE2 12345 +#define PM_ERR_BASE PM_ERR_BASE2 + +/* PMAPI Error Conditions */ + +#define PM_ERR_GENERIC (-PM_ERR_BASE-0) /* Generic error, already reported above */ +#define PM_ERR_PMNS (-PM_ERR_BASE-1) /* Problems parsing PMNS definitions */ +#define PM_ERR_NOPMNS (-PM_ERR_BASE-2) /* PMNS not accessible */ +#define PM_ERR_DUPPMNS (-PM_ERR_BASE-3) /* Attempt to reload the PMNS */ +#define PM_ERR_TEXT (-PM_ERR_BASE-4) /* Oneline or help text is not available */ +#define PM_ERR_APPVERSION (-PM_ERR_BASE-5) /* Metric not supported by this version of monitored application */ +#define PM_ERR_VALUE (-PM_ERR_BASE-6) /* Missing metric value(s) */ +/* retired PM_ERR_LICENSE (-PM_ERR_BASE-7) Current PCP license does not permit this operation */ +#define PM_ERR_TIMEOUT (-PM_ERR_BASE-8) /* Timeout waiting for a response from PMCD */ +#define PM_ERR_NODATA (-PM_ERR_BASE-9) /* Empty archive log file */ +#define PM_ERR_RESET (-PM_ERR_BASE-10) /* pmcd reset or configuration changed */ +/* retired PM_ERR_FILE (-PM_ERR_BASE-11) Cannot locate a file */ +#define PM_ERR_NAME (-PM_ERR_BASE-12) /* Unknown metric name */ +#define PM_ERR_PMID (-PM_ERR_BASE-13) /* Unknown or illegal metric identifier */ +#define PM_ERR_INDOM (-PM_ERR_BASE-14) /* Unknown or illegal instance domain identifier */ +#define PM_ERR_INST (-PM_ERR_BASE-15) /* Unknown or illegal instance identifier */ +#define PM_ERR_UNIT (-PM_ERR_BASE-16) /* Illegal pmUnits specification */ +#define PM_ERR_CONV (-PM_ERR_BASE-17) /* Impossible value or scale conversion */ +#define PM_ERR_TRUNC (-PM_ERR_BASE-18) /* Truncation in value conversion */ +#define PM_ERR_SIGN (-PM_ERR_BASE-19) /* Negative value in conversion to unsigned */ +#define PM_ERR_PROFILE (-PM_ERR_BASE-20) /* Explicit instance identifier(s) required */ +#define PM_ERR_IPC (-PM_ERR_BASE-21) /* IPC protocol failure */ +/* retired PM_ERR_NOASCII (-PM_ERR_BASE-22) ASCII format not supported for this PDU */ +#define PM_ERR_EOF (-PM_ERR_BASE-23) /* IPC channel closed */ +#define PM_ERR_NOTHOST (-PM_ERR_BASE-24) /* Operation requires context with host source of metrics */ +#define PM_ERR_EOL (-PM_ERR_BASE-25) /* End of PCP archive log */ +#define PM_ERR_MODE (-PM_ERR_BASE-26) /* Illegal mode specification */ +#define PM_ERR_LABEL (-PM_ERR_BASE-27) /* Illegal label record at start of a PCP archive log file */ +#define PM_ERR_LOGREC (-PM_ERR_BASE-28) /* Corrupted record in a PCP archive log */ +#define PM_ERR_NOTARCHIVE (-PM_ERR_BASE-29) /* Operation requires context with archive source of metrics */ +#define PM_ERR_LOGFILE (-PM_ERR_BASE-30) /* Missing archive file */ +#define PM_ERR_NOCONTEXT (-PM_ERR_BASE-31) /* Attempt to use an illegal context */ +#define PM_ERR_PROFILESPEC (-PM_ERR_BASE-32) /* NULL pmInDom with non-NULL instlist */ +#define PM_ERR_PMID_LOG (-PM_ERR_BASE-33) /* Metric not defined in the PCP archive log */ +#define PM_ERR_INDOM_LOG (-PM_ERR_BASE-34) /* Instance domain identifier not defined in the PCP archive log */ +#define PM_ERR_INST_LOG (-PM_ERR_BASE-35) /* Instance identifier not defined in the PCP archive log */ +#define PM_ERR_NOPROFILE (-PM_ERR_BASE-36) /* Missing profile - protocol botch */ +#define PM_ERR_NOAGENT (-PM_ERR_BASE-41) /* No pmcd agent for domain of request */ +#define PM_ERR_PERMISSION (-PM_ERR_BASE-42) /* No permission to perform requested operation */ +#define PM_ERR_CONNLIMIT (-PM_ERR_BASE-43) /* PMCD connection limit for this host exceeded */ +#define PM_ERR_AGAIN (-PM_ERR_BASE-44) /* try again. Info not currently available */ +#define PM_ERR_ISCONN (-PM_ERR_BASE-45) /* already connected */ +#define PM_ERR_NOTCONN (-PM_ERR_BASE-46) /* not connected */ +#define PM_ERR_NEEDPORT (-PM_ERR_BASE-47) /* port name required */ +/* retired PM_ERR_WANTACK (-PM_ERR_BASE-48) can not send due to pending acks */ +#define PM_ERR_NONLEAF (-PM_ERR_BASE-49) /* PMNS node is not a leaf node */ +/* retired PM_ERR_OBJSTYLE (-PM_ERR_BASE-50) user/kernel object style mismatch */ +/* retired PM_ERR_PMCDLICENSE (-PM_ERR_BASE-51) PMCD is not licensed to accept connections */ +#define PM_ERR_TYPE (-PM_ERR_BASE-52) /* Unknown or illegal metric type */ +#define PM_ERR_THREAD (-PM_ERR_BASE-53) /* Operation not supported for multi-threaded applications */ + +/* retired PM_ERR_CTXBUSY (-PM_ERR_BASE-97) Context is busy */ +#define PM_ERR_TOOSMALL (-PM_ERR_BASE-98) /* Insufficient elements in list */ +#define PM_ERR_TOOBIG (-PM_ERR_BASE-99) /* Result size exceeded */ +#define PM_ERR_FAULT (-PM_ERR_BASE-100) /* QA fault injected */ + +#define PM_ERR_PMDAREADY (-PM_ERR_BASE-1048) /* now ready to respond */ +#define PM_ERR_PMDANOTREADY (-PM_ERR_BASE-1049) /* not yet ready to respond */ +#define PM_ERR_NYI (-PM_ERR_BASE-8999) /* Functionality not yet implemented [end-of-range mark] */ + +/* + * Report PMAPI errors messages + */ +extern char *pmErrStr(int); /* NOT thread-safe */ +extern char *pmErrStr_r(int, char *, int); +/* safe size for a pmErrStr_r buffer to accommodate all error messages */ +#define PM_MAXERRMSGLEN 128 + +/* + * Load a Performance Metrics Name Space + */ +extern int pmLoadNameSpace(const char *); +extern int pmLoadASCIINameSpace(const char *, int); +extern void pmUnloadNameSpace(void); + +/* + * Where is PMNS located - added for distributed PMNS. + */ +extern int pmGetPMNSLocation(void); +#define PMNS_LOCAL 1 +#define PMNS_REMOTE 2 +#define PMNS_ARCHIVE 3 + +/* + * Trim a name space with respect to the current context + * (usually from an archive, or after processing an archive) + */ +extern int pmTrimNameSpace(void); + +/* + * Expand a list of names to a list of metrics ids + */ +extern int pmLookupName(int, char **, pmID *); + +/* + * Find the names of descendent nodes in the PMNS + * and in the latter case get the status of each child. + */ +extern int pmGetChildren(const char *, char ***); +extern int pmGetChildrenStatus(const char *, char ***, int **); +#define PMNS_LEAF_STATUS 0 /* leaf node in PMNS tree */ +#define PMNS_NONLEAF_STATUS 1 /* non-terminal node in PMNS tree */ + +/* + * Reverse Lookup: find name(s) given a metric id + */ +extern int pmNameID(pmID, char **); /* one */ +extern int pmNameAll(pmID, char ***); /* all */ + +/* + * Handy recursive descent of the PMNS + */ +extern int pmTraversePMNS(const char *, void(*)(const char *)); +extern int pmTraversePMNS_r(const char *, void(*)(const char *, void *), void *); + +/* + * Given a metric, find it's descriptor (caller supplies buffer for desc), + * from the current context. + */ +extern int pmLookupDesc(pmID, pmDesc *); + +/* + * Return the internal instance identifier, from the current context, + * given an instance domain and the external instance name. + * Archive variant scans the union of the indom entries in the archive + * log. + */ +extern int pmLookupInDom(pmInDom, const char *); +extern int pmLookupInDomArchive(pmInDom, const char *); + +/* + * Return the external instance name, from the current context, + * given an instance domain and the internal instance identifier. + * Archive variant scans the union of the indom entries in the archive + * log. + */ +extern int pmNameInDom(pmInDom, int, char **); +extern int pmNameInDomArchive(pmInDom, int, char **); + +/* + * Return all of the internal instance identifiers (instlist) and external + * instance names (namelist) for the given instance domain in the current + * context. + * Archive variant returns the union of the indom entries in the archive + * log. + */ +extern int pmGetInDom(pmInDom, int **, char ***); +extern int pmGetInDomArchive(pmInDom, int **, char ***); + +/* + * Given context ID, return the host name associated with that context, + * or the empty string if no name can be found + */ +extern const char *pmGetContextHostName(int); +extern char *pmGetContextHostName_r(int, char *, int); + +/* + * Return the handle of the current context + */ +extern int pmWhichContext(void); + +/* + * Destroy a context and close its connection + */ +extern int pmDestroyContext(int); + +/* + * Establish a new context (source of performance data + instance profile) + * for the named host + */ +extern int pmNewContext(int, const char *); +#define PM_CONTEXT_UNDEF -1 /* current context is undefined */ +#define PM_CONTEXT_HOST 1 /* host via pmcd */ +#define PM_CONTEXT_ARCHIVE 2 /* PCP archive */ +#define PM_CONTEXT_LOCAL 3 /* local host, no pmcd connection */ +#define PM_CONTEXT_TYPEMASK 0xff /* mask to separate types / flags */ +/* #define PM_CTXFLAG_SHALLOW (1U<<8) -- don't actually connect to host */ +/* #define PM_CTXFLAG_EXCLUSIVE (1U<<9) -- don't share socket among ctxts */ +#define PM_CTXFLAG_SECURE (1U<<10)/* encrypted socket comms channel */ +#define PM_CTXFLAG_COMPRESS (1U<<11)/* compressed socket host channel */ +#define PM_CTXFLAG_RELAXED (1U<<12)/* encrypted if possible else not */ +#define PM_CTXFLAG_AUTH (1U<<13)/* make authenticated connection */ + +/* + * Duplicate current context -- returns handle to new one for pmUseContext() + */ +extern int pmDupContext(void); + +/* + * Restore (previously established or duplicated) context + */ +extern int pmUseContext(int); + +/* + * Reconnect an existing context (when pmcd dies, etc). All existing context + * settings are preserved and the previous context settings are restored. + */ +extern int pmReconnectContext(int); + +/* + * Add to instance profile. + * If pmInDom == PM_INDOM_NULL, then all instance domains are selected. + * If no inst parameters are given, then all instances are selected. + * e.g. to select all available instances in all domains, + * then use pmAddProfile(PM_INDOM_NULL, 0, NULL). + */ +extern int pmAddProfile(pmInDom, int, int *); + +/* + * Delete from instance profile. + * Similar (but negated) functional semantics to pmProfileAdd. + * E.g. to disable all instances in all domains then use + * pmDelProfile(PM_INDOM_NULL, 0, NULL). + */ +extern int pmDelProfile(pmInDom, int, int *); + +/* + * ---------- Collection services ---------- + * + * Result from pmFetch is encoded as a timestamp and vector of pointers + * to pmValueSet instances (one per PMID in the result). + * Each pmValueSet has a PMID, a value count, a value format, and a vector of + * instance-value pairs. Aggregate, string and non-int values are returned + * via one further level of indirection using pmValueBlocks. + * + * timeStamp + * ->pmID + * value format + * instance, value + * instance, value + * ... etc + * + * ->pmID + * value format + * instance, value + * ... etc + * + * + * Notes on pmValueBlock + * 0. may be used for arbitrary binary data + * 1. only ever allocated dynamically, and vbuf expands to accommodate + * an arbitrary value (don't believe the [1] size!) + * 2. len is the length of the len field + the real size of vbuf + * (which includes the null-byte terminator if there is one) + */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int vtype : 8; /* value type */ + unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */ +#else + unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */ + unsigned int vtype : 8; /* value type */ +#endif + char vbuf[1]; /* the value */ +} pmValueBlock; + +#define PM_VAL_HDR_SIZE 4 /* bytes for the vtype/vlen header */ +#define PM_VAL_VLEN_MAX 0x00ffffff /* maximum vbuf[] size */ + +typedef struct { + int inst; /* instance identifier */ + union { + pmValueBlock *pval; /* pointer to value-block */ + int lval; /* integer value insitu (lval 'cuz it WAS a long) */ + } value; +} pmValue; + +typedef struct { + pmID pmid; /* metric identifier */ + int numval; /* number of values */ + int valfmt; /* value style */ + pmValue vlist[1]; /* set of instances/values */ +} pmValueSet; + +/* values for valfmt */ +#define PM_VAL_INSITU 0 /* value.lval is it */ +#define PM_VAL_DPTR 1 /* value.pval->vbuf is it, and dynamic alloc */ +#define PM_VAL_SPTR 2 /* value.pval->vbuf is it, and static alloc */ + + +/* 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, one per PMID */ +} pmResult; + +/* High resolution event timer result from pmUnpackHighResEventRecords() */ +typedef struct { + struct timespec timestamp; /* time stamped by collector */ + int numpmid; /* number of PMIDs */ + pmValueSet *vset[1]; /* set of value sets, one per PMID */ +} pmHighResResult; + +/* Generic Union for Value-Type conversions */ +typedef union { + __int32_t l; /* 32-bit signed */ + __uint32_t ul; /* 32-bit unsigned */ + __int64_t ll; /* 64-bit signed */ + __uint64_t ull; /* 64-bit unsigned */ + float f; /* 32-bit floating point */ + double d; /* 64-bit floating point */ + char *cp; /* char ptr */ + pmValueBlock *vbp; /* pmValueBlock ptr */ +} pmAtomValue; + +/* + * Fetch metrics. Value/instances returned depends on current instance profile. + * By default, all available instances for each requested metric id are + * returned. The metrics argument is terminated with PM_NULL_ID + * + * The value sets returned are in the same order as the metrics argument, + * and the number of value sets returned is guaranteed to be the same as + * the number of metrics in the agument. + */ +extern int pmFetch(int, pmID *, pmResult **); + +/* + * PMCD state changes returned as pmFetch function result for PM_CONTEXT_HOST + * contexts, i.e. when communicating with PMCD + */ +#define PMCD_NO_CHANGE 0 +#define PMCD_ADD_AGENT 1 +#define PMCD_RESTART_AGENT 2 +#define PMCD_DROP_AGENT 4 + +/* + * Variant that is used to return a pmResult from an archive + */ +extern int pmFetchArchive(pmResult **); + +/* + * struct timeval is sometimes 2 x 64-bit ... we use a 2 x 32-bit format for + * PDUs, internally within libpcp and for (external) archive logs + */ +typedef struct { + __int32_t tv_sec; /* seconds since Jan. 1, 1970 */ + __int32_t tv_usec; /* and microseconds */ +} __pmTimeval; + +typedef struct { + __int64_t tv_sec; /* seconds since Jan. 1, 1970 */ + __int64_t tv_nsec; /* and nanoseconds */ +} __pmTimespec; + +/* + * Label Record at the start of every log file - as exported above + * the PMAPI ... + * NOTE MAXHOSTNAMELEN is a bad choice here for ll_hostname[], as + * it may vary on different hosts ... we use PM_LOG_MAXHOSTLEN instead, and + * size this to be the same as MAXHOSTNAMELEN in IRIX 5.3 + * NOTE that the struct timeval means we have another struct (__pmLogLabel) + * for internal use that has a __pmTimeval in place of the struct timeval. + */ +#define PM_TZ_MAXLEN 40 +#define PM_LOG_MAXHOSTLEN 64 +#define PM_LOG_MAGIC 0x50052600 +#define PM_LOG_VERS02 0x2 +#define PM_LOG_VOL_TI -2 /* temporal index */ +#define PM_LOG_VOL_META -1 /* meta data */ +typedef struct { + int ll_magic; /* PM_LOG_MAGIC | log format version no. */ + pid_t ll_pid; /* PID of logger */ + struct timeval ll_start; /* start of this log */ + char ll_hostname[PM_LOG_MAXHOSTLEN]; /* name of collection host */ + char ll_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */ +} pmLogLabel; + +/* + * Get the label record from the current archive context, and discover + * when the archive ends + */ +extern int pmGetArchiveLabel(pmLogLabel *); +extern int pmGetArchiveEnd(struct timeval *); + +/* Free result buffer */ +extern void pmFreeResult(pmResult *); +extern void pmFreeHighResResult(pmHighResResult *); + +/* Value extract from pmValue and type conversion */ +extern int pmExtractValue(int, const pmValue *, int, pmAtomValue *, int); + +/* Print single pmValue */ +extern void pmPrintValue(FILE *, int, int, const pmValue *, int); + +/* Scale conversion, based on value format, value type and scale */ +extern int pmConvScale(int, const pmAtomValue *, const pmUnits *, pmAtomValue *, + const pmUnits *); + +/* Sort instances for each metric within a pmResult */ +extern void pmSortInstances(pmResult *); + +/* Adjust collection time and/or mode for pmFetch */ +extern int pmSetMode(int, const struct timeval *, int); +#define PM_MODE_LIVE 0 +#define PM_MODE_INTERP 1 +#define PM_MODE_FORW 2 +#define PM_MODE_BACK 3 + +/* Modify the value of one or more metrics */ +extern int pmStore(const pmResult *); + +/* Get help and descriptive text */ +extern int pmLookupText(pmID, int, char **); +extern int pmLookupInDomText(pmInDom, int, char **); +#define PM_TEXT_ONELINE 1 +#define PM_TEXT_HELP 2 + +/* + * Some handy formatting routines for messages, and other output + */ +extern const char *pmIDStr(pmID); /* NOT thread-safe */ +extern char *pmIDStr_r(pmID, char *, int); +extern const char *pmInDomStr(pmInDom); /* NOT thread-safe */ +extern char *pmInDomStr_r(pmInDom, char *, int); +extern const char *pmTypeStr(int); /* NOT thread-safe */ +extern char *pmTypeStr_r(int, char *, int); +extern const char *pmUnitsStr(const pmUnits *); /* NOT thread-safe */ +extern char *pmUnitsStr_r(const pmUnits *, char *, int); +extern const char *pmAtomStr(const pmAtomValue *, int); /* NOT thread-safe */ +extern char *pmAtomStr_r(const pmAtomValue *, int, char *, int); +extern const char *pmNumberStr(double); /* NOT thread-safe */ +extern char *pmNumberStr_r(double, char *, int); +extern const char *pmEventFlagsStr(int); /* NOT thread-safe */ +extern char *pmEventFlagsStr_r(int, char *, int); + +/* Extended time base definitions and macros */ +#define PM_XTB_FLAG 0x1000000 + +#define PM_XTB_SET(type) (PM_XTB_FLAG | ((type) << 16)) +#define PM_XTB_GET(x) (((x) & PM_XTB_FLAG) ? (((x) & 0xff0000) >> 16) : -1) + +/* Parse -t, -S, -T, -A and -O options */ +extern int pmParseInterval(const char *, struct timeval *, char **); +extern int pmParseTimeWindow( + const char *, const char *, const char *, const char *, + const struct timeval *, const struct timeval *, + struct timeval *, struct timeval *, struct timeval *, char **); + +/* Reporting timezone */ +extern int pmUseZone(const int); +extern int pmNewZone(const char *); +extern int pmNewContextZone(void); +extern int pmWhichZone(char **); +extern char *pmCtime(const time_t *, char *); +extern struct tm *pmLocaltime(const time_t *, struct tm *); + +/* Parse host:metric[instances] or archive/metric[instances] */ +typedef struct { + int isarch; /* source type: 0 -> live host, 1 -> archive, 2 -> local context */ + char *source; /* name of source host or archive */ + char *metric; /* name of metric */ + int ninst; /* number of instances, 0 -> all */ + char *inst[1]; /* array of instance names */ +} pmMetricSpec; + +/* Parsing of host:metric[instances] or archive/metric[instances] */ +extern int pmParseMetricSpec(const char *, int, char *, pmMetricSpec **, + char **); +extern void pmFreeMetricSpec(pmMetricSpec *p); + +/* + * Configurable error reporting + */ +#ifdef __GNUC__ +# define __PM_PRINTFLIKE(idx,cnt) __attribute__ ((format (printf, idx,cnt))) +#else +# define __PM_PRINTFLIKE(idx,cnt) +#endif + +extern int pmprintf(const char *, ...) __PM_PRINTFLIKE(1,2); +extern int pmflush(void); + +/* + * Wrapper for config/environment variables. Warning: this will exit() with + * a FATAL error if /etc/pcp.conf does not exist and $PCP_CONF is not set. + * Return values point to strings in the environment. + */ +extern char *pmGetConfig(const char *); + +/* + * Common command line argument parsing interfaces + */ + +#define PMAPI_OPTIONS "A:a:D:gh:n:O:p:S:s:T:t:VZ:z?" +#define PMAPI_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) } +#define PMAPI_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) } +#define PMAPI_OPTIONS_END { NULL, 0, 0, 0, NULL } + +#define PMOPT_ALIGN { "align", 1, 'A', "TIME", \ + "align sample times on natural boundaries" } +#define PMOPT_ARCHIVE { "archive", 1, 'a', "FILE", \ + "metrics source is a PCP log archive" } +#define PMOPT_DEBUG { "debug", 1, 'D', "DBG", \ + NULL } +#define PMOPT_GUIMODE { "guimode", 0, 'g', 0, \ + "start in GUI mode with new time control" } +#define PMOPT_HOST { "host", 1, 'h', "HOST", \ + "metrics source is PMCD on host" } +#define PMOPT_HOSTSFILE { "hostsfile", 1, 'H', "FILE", \ + "read metric source hosts from a file" } +#define PMOPT_SPECLOCAL { "spec-local", 1, 'K', "SPEC", \ + "optional additional PMDA spec for local connection" } +#define PMOPT_LOCALPMDA { "local-PMDA", 0, 'L', 0, \ + "metrics source is local connection to a PMDA" } +#define PMOPT_NAMESPACE { "namespace", 1, 'n', "FILE", \ + "use an alternative PMNS" } +#define PMOPT_DUPNAMES { "dupnames", 1, 'N', "FILE", \ + "use an alternative PMNS (duplicate names allowed)" } +#define PMOPT_ORIGIN { "origin", 1, 'O', "TIME", \ + "initial sample time within the time window" } +#define PMOPT_GUIPORT { "guiport", 1, 'p', "N", \ + "port for connection to existing time control" } +#define PMOPT_START { "start", 1, 'S', "TIME", \ + "start of the time window" } +#define PMOPT_SAMPLES { "samples", 1, 's', "N", \ + "terminate after this many samples" } +#define PMOPT_FINISH { "finish", 1, 'T', "TIME", \ + "end of the time window" } +#define PMOPT_INTERVAL { "interval", 1, 't', "DELTA", \ + "sampling interval" } +#define PMOPT_VERSION { "version", 0, 'V', 0, \ + "display version number and exit" } +#define PMOPT_TIMEZONE { "timezone", 1, 'Z', "TZ", \ + "set reporting timezone" } +#define PMOPT_HOSTZONE { "hostzone", 0, 'z', 0, \ + "set reporting timezone to local time of metrics source" } +#define PMOPT_HELP { "help", 0, '?', 0, \ + "show this usage message and exit" } + +#define PMAPI_GENERAL_OPTIONS \ + PMAPI_OPTIONS_HEADER("General options"), \ + PMOPT_ALIGN, \ + PMOPT_ARCHIVE, \ + PMOPT_DEBUG, \ + PMOPT_GUIMODE, \ + PMOPT_HOST, \ + PMOPT_NAMESPACE, \ + PMOPT_ORIGIN, \ + PMOPT_GUIPORT, \ + PMOPT_START, \ + PMOPT_SAMPLES, \ + PMOPT_FINISH, \ + PMOPT_INTERVAL, \ + PMOPT_TIMEZONE, \ + PMOPT_HOSTZONE, \ + PMOPT_VERSION, \ + PMOPT_HELP + +/* long-only standard options */ +#define PMLONGOPT_ARCHIVE_LIST "archive-list" +#define PMOPT_ARCHIVE_LIST { PMLONGOPT_ARCHIVE_LIST, 1, 0, "FILES", \ + "comma-separated list of metric source archives" } +#define PMLONGOPT_ARCHIVE_FOLIO "archive-folio" +#define PMOPT_ARCHIVE_FOLIO { PMLONGOPT_ARCHIVE_FOLIO, 1, 0, "FILE", \ + "read metric source archives from a folio" } +#define PMLONGOPT_HOST_LIST "host-list" +#define PMOPT_HOST_LIST { PMLONGOPT_HOST_LIST, 1, 0, "HOSTS", \ + "comma-separated list of metric source hosts" } + +/* pmOptions flags */ +#define PM_OPTFLAG_INIT (1<<0) /* initialisation done */ +#define PM_OPTFLAG_DONE (1<<1) /* parsing is complete */ +#define PM_OPTFLAG_MULTI (1<<2) /* allow multi-context */ +#define PM_OPTFLAG_USAGE_ERR (1<<3) /* argument parse fail */ +#define PM_OPTFLAG_RUNTIME_ERR (1<<4) /* any runtime failure */ +#define PM_OPTFLAG_EXIT (1<<5) /* tool should exit(0) */ +#define PM_OPTFLAG_POSIX (1<<6) /* POSIXLY_CORRECT set */ +#define PM_OPTFLAG_MIXED (1<<7) /* allow hosts+archives */ +#define PM_OPTFLAG_ENV_ONLY (1<<8) /* use env options only */ +#define PM_OPTFLAG_LONG_ONLY (1<<9) /* use long options only */ +#define PM_OPTFLAG_BOUNDARIES (1<<10) /* calculate time window */ +#define PM_OPTFLAG_STDOUT_TZ (1<<11) /* write timezone change */ +#define PM_OPTFLAG_NOFLUSH (1<<12) /* caller issues pmflush */ +#define PM_OPTFLAG_QUIET (1<<13) /* silence getopt errors */ + +struct __pmOptions; +typedef int (*pmOptionOverride)(int, struct __pmOptions *); + +typedef struct { + const char * long_opt; + int has_arg; + int short_opt; + const char * argname; + const char * message; +} pmLongOptions; + +typedef struct __pmOptions { + int version; + int flags; + + /* in: define set of all options */ + const char * short_options; + pmLongOptions * long_options; + const char * short_usage; + + /* in: method for general override */ + pmOptionOverride override; + + /* out: usual getopt information */ + int index; + int optind; + int opterr; + int optopt; + char *optarg; + + /* internals; do not ever access */ + int __initialized; + char * __nextchar; + int __ordering; + int __posixly_correct; + int __first_nonopt; + int __last_nonopt; + + /* out: error count */ + int errors; + + /* out: PMAPI options and values */ + int context; /* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */ + int nhosts; + int narchives; + char ** hosts; + char ** archives; + struct timeval start; + struct timeval finish; + struct timeval origin; + struct timeval interval; + char * align_optarg; + char * start_optarg; + char * finish_optarg; + char * origin_optarg; + char * guiport_optarg; + char * timezone; + int samples; + int guiport; + int padding; + unsigned int guiflag : 1; + unsigned int tzflag : 1; + unsigned int nsflag : 1; + unsigned int Lflag : 1; + unsigned int zeroes : 28; +} pmOptions; + +extern int pmgetopt_r(int, char *const *, pmOptions *); +extern int pmGetOptions(int, char *const *, pmOptions *); +extern int pmGetContextOptions(int, pmOptions *); +extern void pmUsageMessage(pmOptions *); +extern void pmFreeOptions(pmOptions *); + +/* + * Derived Metrics support + */ +extern int pmLoadDerivedConfig(const char *); +extern char *pmRegisterDerived(const char *, const char *); +extern char *pmDerivedErrStr(void); + +/* + * Event Record support + */ +typedef struct { + pmID ep_pmid; + /* vtype and vlen fields the format same as for pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ep_type : 8; /* value type */ + unsigned int ep_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ep_len : 24; /* bytes for type/len + vbuf */ + unsigned int ep_type : 8; /* value type */ +#endif + /* actual value (vbuf) goes here ... */ +} pmEventParameter; + +typedef struct { + __pmTimeval er_timestamp; /* must be 2 x 32-bit format */ + unsigned int er_flags; /* event record characteristics */ + int er_nparams; /* number of er_param[] entries */ + pmEventParameter er_param[1]; +} pmEventRecord; + +typedef struct { + __pmTimespec er_timestamp; /* must be 2 x 64-bit format */ + unsigned int er_flags; /* event record characteristics */ + int er_nparams; /* number of er_param[] entries */ + pmEventParameter er_param[1]; +} pmHighResEventRecord; + +/* Potential flags bits set in er_flags (above) */ +#define PM_EVENT_FLAG_POINT (1U<<0) /* an observation, default type */ +#define PM_EVENT_FLAG_START (1U<<1) /* marking start of a new event */ +#define PM_EVENT_FLAG_END (1U<<2) /* completion of a traced event */ +#define PM_EVENT_FLAG_ID (1U<<3) /* 1st parameter is a trace ID */ +#define PM_EVENT_FLAG_PARENT (1U<<4) /* 2nd parameter is parents ID */ +#define PM_EVENT_FLAG_MISSED (1U<<31)/* nparams shows #missed events */ + +typedef struct { + /* align initial declarations with start of pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ea_type : 8; /* value type */ + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ + unsigned int ea_type : 8; /* value type */ +#endif + /* real event records start here */ + int ea_nrecords; /* number of ea_record[] entries */ + pmEventRecord ea_record[1]; +} pmEventArray; + +typedef struct { + /* align initial declarations with start of pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ea_type : 8; /* value type */ + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ + unsigned int ea_type : 8; /* value type */ +#endif + /* real event records start here */ + int ea_nrecords; /* number of ea_record[] entries */ + pmHighResEventRecord ea_record[1]; +} pmHighResEventArray; + +/* Unpack a PM_TYPE_EVENT value into a set on pmResults */ +extern int pmUnpackEventRecords(pmValueSet *, int, pmResult ***); + +/* Free set of pmResults from pmUnpackEventRecords */ +extern void pmFreeEventResult(pmResult **); + +/* Unpack a PM_TYPE_HIGHRES_EVENT value into a set on pmHighResResults */ +extern int pmUnpackHighResEventRecords(pmValueSet *, int, pmHighResResult ***); + +/* Free set of pmHighResResults from pmUnpackEventRecords */ +extern void pmFreeHighResEventResult(pmHighResResult **); + +/* Service discovery, for clients. */ +#define PM_SERVER_SERVICE_SPEC "pmcd" +#define PM_SERVER_PROXY_SPEC "pmproxy" +#define PM_SERVER_WEBD_SPEC "pmwebd" + +extern int pmDiscoverServices(const char *, const char *, char ***); + +#ifdef __cplusplus +} +#endif + +#endif /* _PMAPI_H */ |