How to implement a sensor plugin

Below are the steps for implementing a new user defined sensor plugin (udsensor):

1. Include the udsensors.h header file

The udsensors.h file is located at: orcm/common, and it is installed with the rest of the header files of the project. Optionally, the UDExceptions.h header file can be included as well. This provide convenience classes for throwing consistent exceptions to be catched by the monitoring system.

2. Extend the base UDSensor class

Assuming mySensor as the plugin's class name, extend the UDSensor class as follows (The plugin API can be found here):

    class mySensor : public UDSensor
    {
        public:
        mySensor(){};
        virtual ~mySensor(){};
        void init();
        void sample(dataContainer &dc);
        void finalize();
    };

In the constructor method you can define the sensor type of your plugin. The sensor_type variable determines how the plugin is collecting data. The supported types are:

  • IB : in-band
  • OOB : out-of-band

By default, sensor_type is set to IB and can be changed as follows:

    mySensor(){this->sensor_type = OOB;};

Note that OOB sensors are intended to collect metrics from the aggregator node to a device/node not running the monitoring system. As such, they will only run on the aggregator node.

3. Implement the required methods: init, finalize, and sample

The init and finalize methods are intended for resource allocation and deallocation, and hardware management. These methods should be preferred to the constructor and destructor methods of the class, given that it is not possible to throw exception from the latter.

    void mySensor::init()
    {
        std::cout << "On init in plugin" << std::endl;
    }

    void mySensor::sample(dataContainer &dc)
    {
        int random;
        random = rand() % 100;
        std::cout << "On sample, storing random number " << random << std::endl;
        // Storing integer data into the dataContainer object
        dc.put("intValue_1", random, "ints");
    }

    void mySensor::finalize()
    {
        std::cout << "On finalize" << std::endl;
    }

In the case of sampling errors, exception should be used. All exceptions thrown in the udsensor methods are being catched by the underlying layer, so the user does not need to handle those.

There are two different types of exceptions defined in the header file. Currently, they are just both reported to the monitoring system, but in future versions, they will follow different path of execution:

  • The Critical exceptions are related to unrecoverable errors that should stop the sampling process and unloading of the plugin.
  • The Warning exceptions are related to failures that should not stop the sampling process.

Exceptions can be thrown using the throw statement:

    throw udlib::Warning("Warning message");

However, a convenience macro for debugging purposes is provided, which will print the file name information along with the error message:

    UDLIB_THROW(udlib::Critical, "Critical message");

4. Export the plugin into the sensor plugin framework

The user should call the following macro to expose the plugin to SenSys:

    export_plugin(mySensor, "MySensor");

Where mySensor is an instance derived from UDSensor class and "MySensor" is the name which will be used to identify this plugin. The export_plugin macro wraps the details required in order to dynamically load the plugin within the monitoring system. The plugin library will be opened with dlopen and the entry point function of the plugin library will be executed after opening the library with dlsym. Further information about dlopen and dlsym can be found at their respective linux manual pages.