Skip to content
Paul Colby edited this page Feb 11, 2014 · 29 revisions

What is a PMDA?

Performance Co-Pilot (PCP) is an open source infrastructure for monitoring, visualizing, recording, responding to, and controlling the status, activity, and performance of networks, computers, applications, and servers. -- Wikipedia

PCP makes use of add-ons called Performance Metrics Domain Agents (PMDAs) to fetch performance metrics for specific domains, such as database servers, hardware, custom applications, etc.

For more information, see the Performance Co-Pilot Programmer's Guide.

What is PMDA++?

PCP includes support for writing PMDAs in C, Perl and Python. PMDA++ is a header-only library that allows developers to write PMDAs in C++. It is just a light C++ wrapper around PCP's C APIs.

Writing a basic PMDA with PMDA++

Note, this section assumes that you are already familiar with basic PMDA concepts. If you have not already done so, you should read the Performance Co-Pilot Programmer's Guide.

To write a basic PMDA using PMDA++:

  1. Create a new class derived from pcp::pmda.
#include <pcp-cpp/pmda.hpp>

class basic_pmda : public pcp::pmda {

}
  1. Implement the pure-virtual get_pmda_name and get_default_pmda_domain_number functions:
#include <pcp-cpp/pmda.hpp>

class basic_pmda : public pcp::pmda {
public:

    virtual std::string get_pmda_name() const
    {
        return "basic";
    }

    virtual int get_default_pmda_domain_number() const
    {
        return 456;
    }
}
  1. Implement the pure-virtual get_supported_metrics function to declare the metrics this PMDA makes available:
    virtual pcp::metrics_description get_supported_metrics()
    {
        // A single "basic.time" metric, with cluster ID 123 and item ID 456.
        return pcp::metrics_description()(123)
            (456, "time", pcp::type<uint32_t>(), PM_SEM_COUNTER,
             pcp::units(0,1,0, 0,PM_TIME_SEC,0));
    }
  1. Implement the pure-virtual fetch_value function to fetch actual metric value(s):
    virtual fetch_value_result fetch_value(const pcp::pmda::metric_id &metric)
    {
        // Return the current time.
        return pcp::atom(metric.type, time(NULL));
    }
  1. Add either a DSO or daemon entry-point function, or both:
// DSO entry point.
extern "C" void basic_init(pmdaInterface *interface)
{
    pcp::pmda::init_dso<basic_pmda>(interface);
}

// Daemon entry point.
int main(int argc, char *argv[])
{
    return pcp::pmda::run_daemon<basic_pmda>(argc, argv);
}

And that's it! There's a lot of other virtual functions that may be overridden to customize / extend the PMDA's behaviour. See the Reference section below.

For complete, albeit contrived, examples take a look at trivial.cpp and simple.cpp.

For a real-world example, see the Qpid PMDA project (a work in progress).

Reference

Coming soon... Does anyone have suggestions for how to structure this list?