PMDA(3)
π PMDA(3) π
aka PCP::PMDA, straight outta the User Contributed Perl Documentation π
okay bestie, buckle up, we're doing Perl PMDA things and honestly? it's giving main character energy. β¨
β¨ NAME β¨
PCP::PMDA β a Perl extension for Performance Metrics Domain Agents. yeah that's the whole vibe. π
πΈ SYNOPSIS πΈ
use PCP::PMDA;
$pmda = PCP::PMDA->new('myname', $MYDOMAIN);
$pmda->connect_pmcd;
$pmda->add_metric($pmid, $type, $indom, $sem, $units, 'name', '', '');
$pmda->add_indom($indom, [0 => 'white', 1 => 'black', ...], '', '');
$pmda->set_fetch(\&fetch_method);
$pmda->set_refresh(\&refresh_method);
$pmda->set_instance(\&instance_method);
$pmda->set_fetch_callback(\&fetch_callback_method);
$pmda->set_store_callback(\&store_callback_method);
$pmda->set_user('pcp');
$pmda->run;
π¦ DESCRIPTION π¦
The PCP::PMDA Perl module is, like, the language bindings for building Performance Metric Domain Agents (PMDAs) in Perl. periodt.
Every single PMDA exports performance data for one specific domain β could be the operating system kernel, could be Cisco routers, could be a database, could be an application, whatever. each PMDA is its own little universe. π
π METHODS π
no cap, this is the good part. here's every method and exactly what it does.
π PCP::PMDA->new(name, domain)
The PCP::PMDA class constructor, bestie. π
- name is a string that becomes the name of the PMDA for messages, and it also acts as the default prefix for the names of external files used by the PMDA.
- domain is an integer domain number for the PMDA β usually pulled from the register of domain numbers found in
$PCP_VAR_DIR/pmns/stdpmid.
π $pmda->run()
Once all your local setup is complete (that means instance domains and metrics are registered, callbacks are registered β all the stuff discussed below, babe), the PMDA must connect to pmcd(1) to complete its initialisation and start answering client requests for its metrics.
That's literally the whole job of run. Once you invoke it, every bit of interaction inside the PMDA happens via callback routines. which is a fancy way of saying: under normal circumstances, run does not return. it's the final form. π₯
Watch out bestie βrunbehaves differently when either thePCP_PERL_PMNSorPCP_PERL_DOMAINenvironment variables are set. these exist so you can generate the namespace or domain number files, which get used as part of the PMDA installation process. iykyk.
π $pmda->connect_pmcd()
This one lets the PMDA set up the IPC channel to pmcd(1) and complete the credentials handshake with pmcd(1). π«Ά
If you don't explicitly call connect_pmcd, the setup and handshake just happen whenever the run method gets called instead. no biggie.
So why would you call it early? validating. the advantage of explicitly calling connect_pmcd early in the life of the PMDA is that it reduces the risk of a fatal timeout during the credentials handshake β which can absolutely be a problem if your PMDA has a ton of work to do before calling run, like, say, figuring out which metrics and instance domains are available. π
π $pmda->add_indom(indom, insts, help, longhelp)
Time to define a new instance domain, bestie. β¨
- indom is the instance domain identifier β an integer, and it has to be unique across all instance domains for a single PMDA.
- insts defines the instances of the instance domain, and you can hand it over as either a list or a hash.
List form β the contents of the list must give you consecutive pairs of an identifier and an external instance name:
- the identifier is an integer, unique across all instances in the instance domain
- the external instance name is a string, and it must be unique up to the first space (if there even is one) across all instances in the instance domain
like, for example:
@colours = [0 => 'red', 1 => 'green', 2 => 'blue'];
Hash form β the external instance identifier (a string) is used as the hash key, and you can store an arbitrary value along with that key. (people often use that value as a convenient lil spot to hold the latest value for each metric instance, for example.)
%timeslices = ('sec' => 42, 'min' => \&min_func, 'hour' => '0');
The help and longhelp strings are read as the one-line and expanded help text to be used for this instance domain β further described in pmLookupInDomText(3).
Also, go check out the replace_indom() discussion further down for more deets on manipulating instance domains. π
π $pmda->add_metric(pmid, type, indom, sem, units, name, help, longhelp)
Define a new metric, identified by the PMID pmid and the full metric name name. π
The metric's metadata is defined by type, indom, sem and units, and those parameters get used to set up the pmDesc structure as described in pmLookupDesc(3).
The help and longhelp strings are read as the one-line and expanded help text for the metric β further described in pmLookupText(3).
π $pmda->replace_indom(index, insts)
Whenever an instance domain identified by index β one you previously registered using add_indom() β changes in any way, you have to reflect that change by replacing the existing mapping with a new one (insts).
Heads up babe: the replacement mapping must be a hash if the instance domain was originally registered with add_indom() as a hash. otherwise? it must be a list. no mixing. π
Go look back at the earlier add_indom() discussion about those two different types of instance domain definitions. π
π $pmda->load_indom(index)
When you're working with hash-based instance domains, changes get automatically persisted when you use replace_indom() β and that persisted indom can be restored (say, on startup) using this interface. iconic behaviour fr fr.
- the instance domain to be loaded is identified by index β one you previously registered using
add_indom().
Refer back to the earlier add_indom() discussion about the two different types of instance domain definitions β and remember: only hash-based instance domains are persisted. π«Ά
π $pmda->add_pipe(command, callback, data)
This one lets you inject data into the PMDA using a pipe(2). π¦
The given command gets run early in the life of the PMDA, and a pipe is formed between the PMDA and that command. Line-oriented output is assumed (otherwise truncation will occur π), and on receipt of each line of text on the pipe, the callback function gets called.
The optional data parameter lets you specify extra data to pass into the callback routine. π
π $pmda->add_sock(hostname, port, callback, data)
Creates a socket(2) connection to the hostname, port pair. Whenever data arrives (and like above, a line-oriented protocol is best), the callback function gets called.
The optional data parameter lets you specify extra data to pass into the callback routine.
An opaque integer-sized identifier for the socket gets returned, which you can later use in calls to put_sock() β discussed below. β¨
π $pmda->put_sock(id, output)
Writes an output string to the socket identified by id, which must refer to a socket previously registered using add_sock(). no shortcuts, bestie. π
π $pmda->add_tail(filename, callback, data)
Monitors the given filename for the arrival of newly appended information. π
Line-oriented input is assumed (otherwise truncation will occur), and on receipt of each line of text on the pipe, the callback function gets called.
The optional data parameter lets you specify extra data to pass into the callback routine.
This interface deals with the issue of the file being renamed (like, say, on daily log file rotation), and it'll attempt to automatically re-route information from the new log file if that happens. slay. πΈ
π $pmda->add_timer(timeout, callback, data)
Registers a timer with the PMDA, so that on expiry of a timeout a callback routine gets called. and btw, it's a repeating timer. β°
The optional data parameter lets you specify extra data to pass into the callback routine.
π $pmda->err(message)
Report a timestamped error message into the PMDA log file. β¨
π $pmda->error(message)
Report a timestamped error message into the PMDA log file. (yep, twin of the one above β same energy, same job π)
π $pmda->log(message)
Report a timestamped informational message into the PMDA log file. π
π $pmda->set_fetch_callback(cb_function)
Register a callback function akin to pmdaSetFetchCallBack(3). π
π $pmda->set_fetch(function)
Register a fetch function, as used by pmdaInit(3). π
π $pmda->set_instance(function)
Register an instance function, as used by pmdaInit(3). π¦
π $pmda->set_refresh(function)
Register a refresh function, which gets called once per metric cluster, during the fetch operation. π
Only clusters being requested during this fetch will be refreshed, which is how you get selective metric value updates inside the PMDA. obsessed.
π $pmda->set_store_callback(cb_function)
Register a store function, used indirectly by pmdaInit(3).
The cb_function is called once for each metric/instance pair into which a pmStore(3) is performed. π«Ά
π $pmda->set_inet_socket(port)
Specify the IPv4 socket port to be used to communicate with pmcd(1). π
π $pmda->set_ipv6_socket(port)
Specify the IPv6 socket port to be used to communicate with pmcd(1). π
π $pmda->set_unix_socket(socket_name)
Specify the filesystem socket_name path to be used for communication with pmcd(1). π
π $pmda->set_user(username)
Run the PMDA under the username user account, instead of the default (root) user. π
β¨ HELPER METHODS β¨
pmda_pmid(cluster, item)β constructs a Performance Metric Identifier (PMID) from the domain number (passed as an argument to thenewconstructor), the cluster (an integer in the range0to2^12-1) and the item (an integer in the range0to2^10-1). π
Every performance metric exported from a PMDA must have a unique PMID. No cap.
pmda_pmid_name(cluster, item)β does a reverse metric identifier to name lookup: give it the metric cluster and item numbers, and it returns the metric name string. Reverse it, bestie. β¨pmda_pmid_text(cluster, item)β returns the one-line metric help text string: give it the metric cluster and item numbers, and it returns the help text string. πpmda_inst_name(index, instance)β reverse instance identifier to instance name lookup for the instance domain identified by index. Given the internal instance identifier, it returns the external instance name string. π¦pmda_inst_lookup(index, instance)β given an internal instance identifier (key) for the instance domain identified by index 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). Iconic.pmda_units(dim_space, dim_time, dim_count, scale_space, scale_time, scale_count)β constructs apmUnitsstructure suitable for registering a metric's metadata viaadd_metric(). πΈpmda_extraunits(dim_space, dim_time, dim_count, scale_space, scale_time, scale_count, extra_unit, extra_scale)β constructs apmUnitsstructure with extra units suitable for registering a metric's metadata viaadd_metric(). Extra units, extra slay.pmda_config(name)β looks up the value for configuration variable name from the/etc/pcp.conffile, usingpmGetConfig(3). πpmda_uptime(now)β returns a human-readable uptime string, based on now seconds since the epoch. β³pmda_long()β returns eitherPM_TYPE_32orPM_TYPE_64depending on the platform size for a signed long integer. βpmda_ulong()β returns eitherPM_TYPE_U32orPM_TYPE_U64depending on the platform size for an unsigned long integer. βpmda_install()β Boolean result indicating whether PMDA installation is in progress, or if this is an actual PMDA invocation viapmcd(1). Vibe check: installing or live?
π MACROS π
Most of the PM_* macros from the PCP C headers are available. Periodt.
For example the type of a metric's value may be directly specified as one of PM_TYPE_32, PM_TYPE_U32, PM_TYPE_64, PM_TYPE_U64, PM_TYPE_FLOAT, PM_TYPE_DOUBLE, PM_TYPE_STRING or PM_TYPE_NOSUPPORT. Pick your type, bestie.
π«Ά DEBUGGING π«Ά
Perl PMDAs do not follow the -D convention of other PCP applications for enabling run-time diagnostics and tracing. Not me finding out the usual -D thing doesn't work here. Rather the environment variable PCP_PERL_DEBUG needs to be set to a string value matching the syntax accepted for the option value for -D elsewhere, see pmSetDebug(3).
This requires a little trickery. The pmcd(1) configuration file (PCP_PMCDCONF_PATH from /etc/pcp.conf) needs hand editing. This is best demonstrated by example.
Replace this line:
foo 242 pipe binary python /somepath/foo.py
with:
foo 242 pipe binary python \
sh -c "PCP_PERL_DEBUG=pdu,fetch /usr/bin/python /somepath/foo.py"
Hand-edit era, iykyk. π
π SEE ALSO π
perl(1) and PCPIntro(1). π
The PCP mailing list pcp@groups.io can be used for questions about this module. Ask away, bestie.
Further details can be found at https://pcp.io. π
π AUTHOR π
The Performance Co-Pilot development team. Legends only. π
Copyright (C) 2014 Red Hat. Copyright (C) 2008-2010 Aconex. Copyright (C) 2004 Silicon Graphics, Inc. π
This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2 (see the "COPYING" file in the PCP source tree for further details). π
This page is from the PCP PMDA(3) docs, source/version perl v5.42.3, dated 2026-10-19. She's giving classic manpage, and she ate. Byeee. π
β¨
π¦ where this page comes from
- fedora 43: perl-PCP-PMDA 7.2.2-2.fc43 Β· GPL-2.0-or-later
- fedora 44: perl-PCP-PMDA 7.2.2-2.fc44 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms