Below are the steps for developing a new analytics plugin:

1. Include the "analytics_interface.h" and the "analytics_factory.h" header files
2. Extend the base "Analytics" class (refer to section 4.4.1 for the plugin API)
3. Add a static creator function declaration in the class
4. Implement the "analyze" and creator functions, as well as the constructor and destructor of the class
5. Add a function named "initPlugin" as the entry point function of the plugin library

##Step 1: Include the "analytics_interface.h" and the "analytics_factory.h" header files The "analytics_interface.h" file is located at: "orcm/mca/analytics", while the "analytics_factory.h" is located at: "orcm/mca/analytics/base"

##Step 2: Extend the base "Analytics" class Assuming user wants to develop a plugin that computes the instant average value of a collected sample and names the plugins's class as "Average". The "Average" class will need to extend the "Analytics" class as follows:

class Average : public Analytics {
    public:
        Average();
        virtual ~Average();
        int analyze(DataSet& data_set);
    private:
        Average(Average const &);
}

##Step 3: Add a static creator function declaration in the class The creator function does nothing except for creating an object of this plugin class. Since analytics plugin objects of different plugins are created on-the-fly according to the workflows submitted, the creator makes sure that the correct plugin will be created corresponding to a workflow step. The creator function must have signature like this:

static Analytics* func_name(void)

Assuming the func_name is "creator", then the "Average" class will be:

class Average : public Analytics {
    public:
        Average();
        virtual ~Average();
        int analyze(DataSet& data_set);
        static Analytics* creator(void);
    private:
        Average(Average const &);
}

Step 4: Implement the "analyze" and creator functions, as well as the constructor and destructor of the class

The constructor and destructor are for initializing and destructing members. For example, when doing running average, the developer could define a member variable that holds the historic "average" value and the number of data point received so far. This variable could be initialized in the constructor.

Implement the creator function: The creator function is implemented as follows:

Analytics* Average::creator()
{
    Analytics* average = new Average();
    return average;
}

Implement the analyze function: The analyze function conducts the analytics logic and generates the results and events as needed. For example, the analyze function of the "Average" plugin class could be implemented as follows:

int Average::analyze(DataSet& data_set)
{
    // compute the sample average
    dataContainer::iterator it = data_set.compute.begin();
    double avg = 0.0, sum = 0.0;
    int num_data_point = 0;
    while (it != data_set.compute.end()) {
        sum += data_set.compute.getValue<double>(it);
        num_data_point++;
        it++;
    }
    avg = sum / num_data_point;
    data_set.results.put<double>("example_key", avg, "C");

    // create an event
    Event ev = {"crit", "syslog", "test example", avg, "C"};
    data_set.events.push_back(ev);

    return ANALYTICS_SUCCESS;
}

##Step 5: Add a function named "initPlugin" as the entry point function of the plugin library The plugin library will be opened with "dlopen" (refer to the linux manual page), and the entry point function of the plugin library will be executed after opening the library with "dlsym" (refers to the linux manual page). The entry point function must be named as "initPlugin", and the signature of "initPlugin" is as follows:

void initPlugin(void);

The "initPlugin" function should be implemented as follows, assuming the plugin name is "average":

extern "C" {
    void initPlugin(void) {
        AnalyticsFactory* factory = AnalyticsFactory::getInstance();
        factory->setPluginCreator("average", Average::creator);
   }
}

This function is to put the pair <"average", Average::creator> in the map of plugins of the singleton AnalyticsFactory. Later, when a workflow is submitted, the factory could create the corresponding plugin object for each workflow step using the creator function of the plugin.

The complete code of the "Average" plugin could be found at: "orcm/mca/analytics/extension_plugins/average"