.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "PMDA 3pm" .TH PMDA 3pm "2019-06-20" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" PCP::PMDA \- Perl extension for Performance Metrics Domain Agents .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use PCP::PMDA; \& \& $pmda = PCP::PMDA\->new(\*(Aqmyname\*(Aq, $MYDOMAIN); \& \& $pmda\->connect_pmcd; \& \& $pmda\->add_metric($pmid, $type, $indom, $sem, $units, \*(Aqname\*(Aq, \*(Aq\*(Aq, \*(Aq\*(Aq); \& $pmda\->add_indom($indom, [0 => \*(Aqwhite\*(Aq, 1 => \*(Aqblack\*(Aq, ...], \*(Aq\*(Aq, \*(Aq\*(Aq); \& \& $pmda\->set_fetch(\e&fetch_method); \& $pmda\->set_refresh(\e&refresh_method); \& $pmda\->set_instance(\e&instance_method); \& $pmda\->set_fetch_callback(\e&fetch_callback_method); \& $pmda\->set_store_callback(\e&store_callback_method); \& \& $pmda\->set_user(\*(Aqpcp\*(Aq); \& \& $pmda\->run; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The \s-1PCP::PMDA\s0 Perl module contains the language bindings for building Performance Metric Domain Agents (PMDAs) using Perl. Each \s-1PMDA\s0 exports performance data for one specific domain, for example the operating system kernel, Cisco routers, a database, an application, etc. .SH "METHODS" .IX Header "METHODS" .IP "\s-1PCP::PMDA\-\s0>new(name, domain)" 4 .IX Item "PCP::PMDA->new(name, domain)" \&\s-1PCP::PMDA\s0 class constructor. \fIname\fR is a string that becomes the name of the \s-1PMDA\s0 for messages and default prefix for the names of external files used by the \s-1PMDA.\s0 \fIdomain\fR is an integer domain number for the \s-1PMDA,\s0 usually from the register of domain numbers found in \fB\f(CB$PCP_VAR_DIR\fB/pmns/stdpmid\fR. .ie n .IP "$pmda\->\fBrun()\fR" 4 .el .IP "\f(CW$pmda\fR\->\fBrun()\fR" 4 .IX Item "$pmda->run()" Once all local setup is complete (i.e. instance domains and metrics are registered, callbacks registered \- as discussed below) the \s-1PMDA\s0 must connect to \fBpmcd\fR(1) to complete its initialisation and begin answering client requests for its metrics. This is the role performed by \fIrun\fR, and upon invoking it all interaction within the \s-1PMDA\s0 is done via callback routines (that is to say, under normal cicrumstances, the \fIrun\fR routine does not return). .Sp The behaviour of the \fIrun\fR method is different in the presence of either the \fB\s-1PCP_PERL_PMNS\s0\fR or \fB\s-1PCP_PERL_DOMAIN\s0\fR environment variables. These can be used to generate the namespace or domain number files, which are used as part of the \s-1PMDA\s0 installation process. .ie n .IP "$pmda\->\fBconnect_pmcd()\fR" 4 .el .IP "\f(CW$pmda\fR\->\fBconnect_pmcd()\fR" 4 .IX Item "$pmda->connect_pmcd()" Allows the \s-1PMDA\s0 to set up the \s-1IPC\s0 channel to \fBpmcd\fR(1) and complete the credentials handshake with \fBpmcd\fR(1). If \fIconnect_pmcd\fR is not explicitly called the setup and handshake will be done when the \&\fIrun\fR method is called. .Sp The advantage of explicitly calling \fIconnect_pmcd\fR early in the life of the \s-1PMDA\s0 is that this reduces the risk of a fatal timeout during the credentials handshake, which may be an issue if the \s-1PMDA\s0 has considerable work to do, e.g. determining which metrics and instance domains are available, before calling \fIrun\fR. .ie n .IP "$pmda\->add_indom(indom, insts, help, longhelp)" 4 .el .IP "\f(CW$pmda\fR\->add_indom(indom, insts, help, longhelp)" 4 .IX Item "$pmda->add_indom(indom, insts, help, longhelp)" Define a new instance domain. The instance domain identifier is \&\fIindom\fR, which is an integer and unique across all instance domains for single \s-1PMDA.\s0 .Sp The instances of the instance domain are defined by \fIinsts\fR which can be specified as either a list or a hash. .Sp In list form, the contents of the list must provide consecutive pairs of identifier (a integer, unique across all instances in the instance domain) and external instance name (a string, must by unique up to the first space, if any, across all instances in the instance domain). For example: .Sp .Vb 1 \& @colours = [0 => \*(Aqred\*(Aq, 1 => \*(Aqgreen\*(Aq, 2 => \*(Aqblue\*(Aq]; .Ve .Sp In hash form, the external instance identifier (string) is used as the hash key. An arbitrary value can be stored along with the key (this value is often used as a convenient place to hold the latest value for each metric instance, for example). .Sp .Vb 1 \& %timeslices = (\*(Aqsec\*(Aq => 42, \*(Aqmin\*(Aq => \e&min_func, \*(Aqhour\*(Aq => \*(Aq0\*(Aq); .Ve .Sp The \fIhelp\fR and \fIlonghelp\fR strings are interpreted as the one-line and expanded help text to be used for this instance domain as further described in \fBpmLookupInDomText\fR(3). .Sp Refer also to the \fBreplace_indom\fR() discussion below for further details about manipulating instance domains. .ie n .IP "$pmda\->add_metric(pmid, type, indom, sem, units, name, help, longhelp)" 4 .el .IP "\f(CW$pmda\fR\->add_metric(pmid, type, indom, sem, units, name, help, longhelp)" 4 .IX Item "$pmda->add_metric(pmid, type, indom, sem, units, name, help, longhelp)" Define a new metric identified by the \s-1PMID\s0 \fIpmid\fR and the full metric name \fIname\fR. .Sp The metric's metadata is defined by \fItype\fR, \fIindom\fR, \fIsem\fR and \&\fIunits\fR and these parameters are used to set up the \fIpmDesc\fR structure as described in \fBpmLookupDesc\fR(3). .Sp The \fIhelp\fR and \fIlonghelp\fR strings are interpreted as the one-line and expanded help text to be used for the metric as further described in \fBpmLookupText\fR(3). .ie n .IP "$pmda\->replace_indom(index, insts)" 4 .el .IP "\f(CW$pmda\fR\->replace_indom(index, insts)" 4 .IX Item "$pmda->replace_indom(index, insts)" Whenever an instance domain identified by \fIindex\fR, previously registered using \fBadd_indom\fR(), changes in any way, this change must be reflected by replacing the existing mapping with a new one (\fIinsts\fR). .Sp The replacement mapping must be a hash if the instance domain was registered initially with \fBadd_indom\fR() as a hash, otherwise it must be a list. .Sp Refer to the earlier \fBadd_indom\fR() discussion concerning these two different types of instance domains definitions. .ie n .IP "$pmda\->load_indom(index)" 4 .el .IP "\f(CW$pmda\fR\->load_indom(index)" 4 .IX Item "$pmda->load_indom(index)" When hash-based instance domains are in use, changes are automatically persisted when using \fBreplace_indom\fR() \- this persisted indom can be restored (e.g. on startup) using this interface. .Sp The instance domain to be loaded is identified by \fIindex\fR, previously registered using \fBadd_indom\fR(). .Sp Refer to the earlier \fBadd_indom\fR() discussion concerning the two different types of instance domains definitions \- only hash-based instance domains are persisted. .ie n .IP "$pmda\->add_pipe(command, callback, data)" 4 .el .IP "\f(CW$pmda\fR\->add_pipe(command, callback, data)" 4 .IX Item "$pmda->add_pipe(command, callback, data)" Allow data to be injected into the \s-1PMDA\s0 using a \fBpipe\fR(2). .Sp The given \fIcommand\fR is run early in the life of the \s-1PMDA,\s0 and a pipe is formed between the \s-1PMDA\s0 and the \fIcommand\fR. Line-oriented output is assumed (else truncation will occur), and on receipt of each line of text on the pipe, the \fIcallback\fR function will be called. .Sp The optional \fIdata\fR parameter can be used to specify extra data to pass into the \fIcallback\fR routine. .ie n .IP "$pmda\->add_sock(hostname, port, callback, data)" 4 .el .IP "\f(CW$pmda\fR\->add_sock(hostname, port, callback, data)" 4 .IX Item "$pmda->add_sock(hostname, port, callback, data)" Create a \fBsocket\fR(2) connection to the \fIhostname\fR, \fIport\fR pair. Whenever data arrives (as above, a line-oriented protocol is best) the \fIcallback\fR function will be called. .Sp The optional \fIdata\fR parameter can be used to specify extra data to pass into the \fIcallback\fR routine. .Sp An opaque integer-sized identifier for the socket will be returned, which can later be used in calls to \fBput_sock\fR() as discussed below. .ie n .IP "$pmda\->put_sock(id, output)" 4 .el .IP "\f(CW$pmda\fR\->put_sock(id, output)" 4 .IX Item "$pmda->put_sock(id, output)" Write an \fIoutput\fR string to the socket identified by \fIid\fR, which must refer to a socket previously registered using \fBadd_sock\fR(). .ie n .IP "$pmda\->add_tail(filename, callback, data)" 4 .el .IP "\f(CW$pmda\fR\->add_tail(filename, callback, data)" 4 .IX Item "$pmda->add_tail(filename, callback, data)" Monitor the given \fIfilename\fR for the arrival of newly appended information. Line-oriented input is assumed (else truncation will occur), and on receipt of each line of text on the pipe, the \fIcallback\fR function will be called. .Sp The optional \fIdata\fR parameter can be used to specify extra data to pass into the \fIcallback\fR routine. .Sp This interface deals with the issue of the file being renamed (such as on daily log file rotation), and will attempt to automatically re-route information from the new log file if this occurs. .ie n .IP "$pmda\->add_timer(timeout, callback, data)" 4 .el .IP "\f(CW$pmda\fR\->add_timer(timeout, callback, data)" 4 .IX Item "$pmda->add_timer(timeout, callback, data)" Registers a timer with the \s-1PMDA,\s0 such that on expiry of a \fItimeout\fR a \fIcallback\fR routine will be called. This is a repeating timer. .Sp The optional \fIdata\fR parameter can be used to specify extra data to pass into the \fIcallback\fR routine. .ie n .IP "$pmda\->err(message)" 4 .el .IP "\f(CW$pmda\fR\->err(message)" 4 .IX Item "$pmda->err(message)" Report a timestamped error message into the \s-1PMDA\s0 log file. .ie n .IP "$pmda\->error(message)" 4 .el .IP "\f(CW$pmda\fR\->error(message)" 4 .IX Item "$pmda->error(message)" Report a timestamped error message into the \s-1PMDA\s0 log file. .ie n .IP "$pmda\->log(message)" 4 .el .IP "\f(CW$pmda\fR\->log(message)" 4 .IX Item "$pmda->log(message)" Report a timestamped informational message into the \s-1PMDA\s0 log file. .ie n .IP "$pmda\->set_fetch_callback(cb_function)" 4 .el .IP "\f(CW$pmda\fR\->set_fetch_callback(cb_function)" 4 .IX Item "$pmda->set_fetch_callback(cb_function)" Register a callback function akin to \fBpmdaSetFetchCallBack\fR(3). .ie n .IP "$pmda\->set_fetch(function)" 4 .el .IP "\f(CW$pmda\fR\->set_fetch(function)" 4 .IX Item "$pmda->set_fetch(function)" Register a fetch function, as used by \fBpmdaInit\fR(3). .ie n .IP "$pmda\->set_instance(function)" 4 .el .IP "\f(CW$pmda\fR\->set_instance(function)" 4 .IX Item "$pmda->set_instance(function)" Register an instance function, as used by \fBpmdaInit\fR(3). .ie n .IP "$pmda\->set_refresh(function)" 4 .el .IP "\f(CW$pmda\fR\->set_refresh(function)" 4 .IX Item "$pmda->set_refresh(function)" Register a refresh function, which will be called once per metric cluster, during the fetch operation. Only clusters being requested during this fetch will be refreshed, allowing selective metric value updates within the \s-1PMDA.\s0 .ie n .IP "$pmda\->set_store_callback(cb_function)" 4 .el .IP "\f(CW$pmda\fR\->set_store_callback(cb_function)" 4 .IX Item "$pmda->set_store_callback(cb_function)" Register an store function, used indirectly by \fBpmdaInit\fR(3). The \fIcb_function\fR is called once for each metric/instance pair into which a \fBpmStore\fR(3) is performed. .ie n .IP "$pmda\->set_inet_socket(port)" 4 .el .IP "\f(CW$pmda\fR\->set_inet_socket(port)" 4 .IX Item "$pmda->set_inet_socket(port)" Specify the IPv4 socket \fIport\fR to be used to communicate with \fBpmcd\fR(1). .ie n .IP "$pmda\->set_ipv6_socket(port)" 4 .el .IP "\f(CW$pmda\fR\->set_ipv6_socket(port)" 4 .IX Item "$pmda->set_ipv6_socket(port)" Specify the IPv6 socket \fIport\fR to be used to communicate with \fBpmcd\fR(1). .ie n .IP "$pmda\->set_unix_socket(socket_name)" 4 .el .IP "\f(CW$pmda\fR\->set_unix_socket(socket_name)" 4 .IX Item "$pmda->set_unix_socket(socket_name)" Specify the filesystem \fIsocket_name\fR path to be used for communication with \fBpmcd\fR(1). .ie n .IP "$pmda\->set_user(username)" 4 .el .IP "\f(CW$pmda\fR\->set_user(username)" 4 .IX Item "$pmda->set_user(username)" Run the \s-1PMDA\s0 under the \fIusername\fR user account, instead of the default (root) user. .SH "HELPER METHODS" .IX Header "HELPER METHODS" .IP "pmda_pmid(cluster, item)" 4 .IX Item "pmda_pmid(cluster, item)" Construct a Performance Metric Identifier (\s-1PMID\s0) from the domain number (passed as an argument to the \fInew\fR constructor), the \&\fIcluster\fR (an integer in the range 0 to 2^12\-1) and the \&\fIitem\fR (an integer in the range 0 to 2^10\-1). .Sp Every performance metric exported from a \s-1PMDA\s0 must have a unique \&\s-1PMID.\s0 .IP "pmda_pmid_name(cluster, item)" 4 .IX Item "pmda_pmid_name(cluster, item)" Perform a reverse metric identifier to name lookup \- given the metric \&\fIcluster\fR and \fIitem\fR numbers, returns the metric name string. .IP "pmda_pmid_text(cluster, item)" 4 .IX Item "pmda_pmid_text(cluster, item)" Returns the one-line metric help text string \- given the metric \&\fIcluster\fR and \fIitem\fR numbers, returns the help text string. .IP "pmda_inst_name(index, instance)" 4 .IX Item "pmda_inst_name(index, instance)" Perform a reverse instance identifier to instance name lookup for the instance domain identified by \fIindex\fR. Given the internal \fIinstance\fR identifier, returns the external instance name string. .IP "pmda_inst_lookup(index, instance)" 4 .IX Item "pmda_inst_lookup(index, instance)" Given an internal \fIinstance\fR identifier (key) for the instance domain identified by \fIindex\fR with an associated indom hash, return the value associated with that key. The value can be any scalar value (this includes references, of course, so complex data structures can be referenced). .IP "pmda_units(dim_space, dim_time, dim_count, scale_space, scale_time, scale_count)" 4 .IX Item "pmda_units(dim_space, dim_time, dim_count, scale_space, scale_time, scale_count)" Construct a \fBpmUnits\fR structure suitable for registering a metrics metadata via \fBadd_metric\fR(). .IP "pmda_config(name)" 4 .IX Item "pmda_config(name)" Lookup the value for configuration variable \fIname\fR from the \&\fI/etc/pcp.conf\fR file, using \fBpmGetConfig\fR(3). .IP "pmda_uptime(now)" 4 .IX Item "pmda_uptime(now)" Return a human-readable uptime string, based on \fInow\fR seconds since the epoch. .IP "\fBpmda_long()\fR" 4 .IX Item "pmda_long()" Return either \s-1PM_TYPE_32\s0 or \s-1PM_TYPE_64\s0 depending on the platform size for a signed long integer. .IP "\fBpmda_ulong()\fR" 4 .IX Item "pmda_ulong()" Return either \s-1PM_TYPE_U32\s0 or \s-1PM_TYPE_U64\s0 depending on the platform size for an unsigned long integer. .IP "\fBpmda_install()\fR" 4 .IX Item "pmda_install()" Boolean result indicating whether \s-1PMDA\s0 installation is in progress, or if this is an actual \s-1PMDA\s0 invocation via \fBpmcd\fR(1). .SH "MACROS" .IX Header "MACROS" Most of the PM_* macros from the \s-1PCP C\s0 headers are available. .PP For example the \fItype\fR of a metric's value may be directly specified as one of \&\fB\s-1PM_TYPE_32\s0\fR, \fB\s-1PM_TYPE_U32\s0\fR, \fB\s-1PM_TYPE_64\s0\fR, \fB\s-1PM_TYPE_U64\s0\fR, \&\fB\s-1PM_TYPE_FLOAT\s0\fR, \fB\s-1PM_TYPE_DOUBLE\s0\fR, \fB\s-1PM_TYPE_STRING\s0\fR or \&\fB\s-1PM_TYPE_NOSUPPORT\s0\fR. .SH "DEBUGGING" .IX Header "DEBUGGING" Perl PMDAs do not follow the \fB\-D\fR convention of other \s-1PCP\s0 applications for enabling run-time diagnostics and tracing. Rather the environment variable \fB\s-1PCP_PERL_DEBUG\s0\fR needs to be set to a string value matching the syntax accepted for the option value for \fB\-D\fR elsewhere, see \&\fBpmSetDebug\fR(3). .PP This requires a little trickery. The \fBpmcd\fR(1) configuration file (\fB\s-1PCP_PMCDCONF_PATH\s0\fR from \fI/etc/pcp.conf\fR) needs hand editing. This is best demonstrated by example. .PP Replace this line .PP .Vb 1 \& foo 242 pipe binary python /somepath/foo.py .Ve .PP with .PP .Vb 2 \& foo 242 pipe binary python \e \& sh \-c "PCP_PERL_DEBUG=pdu,fetch /usr/bin/python /somepath/foo.py" .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBperl\fR\|(1) and \fBPCPIntro\fR\|(1). .PP The \s-1PCP\s0 mailing list pcp@groups.io can be used for questions about this module. .PP Further details can be found at https://pcp.io .SH "AUTHOR" .IX Header "AUTHOR" The Performance Co-Pilot development team. .PP Copyright (C) 2014 Red Hat. Copyright (C) 2008\-2010 Aconex. Copyright (C) 2004 Silicon Graphics, Inc. .PP This library is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License, version 2 (see the \*(L"\s-1COPYING\*(R"\s0 file in the \s-1PCP\s0 source tree for further details).