Plugin Development Guide
Introduction
This plugin development guide contains documentation for users who wish to create their own plugins. Use this documentation to learn how to create plugins that solve your business needs.
What is a plugin?
A computer add-on, also known as a plugin, is an application that allows you to extend the features of another application, in this case Pandora FMS.
Why are plugins useful?
Plugins allow to extend Pandora FMS features, which offers a wide variety of possibilities when developing new options for monitoring.
By means of their use you may integrate service, application or database monitoring, among others, and much more, they can even be used to modify or automate tasks and processes.
One of the objectives is to be able to monitor as many systems and services as possible in the same work environment and the use of plugins helps a lot with that task.
Most plugins are useful to be able to display data or performance statistics collected from external services in Pandora FMS.
Plugin Types in Pandora FMS
By execution type:
- Agent plugin: Agent plugins are run by Pandora FMS software agent, they are usually local and do not work remotely, so execution will be performed by the agent daemon. Agent plugins usually generate an XML in their execution, modules with data.
- Server plugin: Server plugins are executed by the server plugin, they usually retrieve data remotely, either by API or another method, so although they can be configured as an agent plugin (mostly), the recommended option is to configure them as a server plugin. Server plugins generate only one value, such as a
1
to indicate their successful execution.
How do users find plugins?
Pandora FMS has a library from which you may download all plugins created for the system.
Anyone may upload plugins to the library, although there is a review process before these are accepted and published.
Currently the library has a large number of plugins that cover all fields, databases, applications, Cloud, messaging services,…
The library has a search engine with which you may search for any plugin uploaded to it, in addition to different tags and menus with which you may browse easily.
Each plugin is usually accompanied by its documentation detailing the installation, configuration of the plugin and the data it collects.
How to install plugins?
Plugins can be installed from Pandora FMS console. Depending on their type they can be run in two different ways, which will create different ways of plugin configuration. Agent plugins are however run by the software agent, while server plugins are run by the plugin server. Usually server plugins create agents and modules while agent plugins only create modules within the software agent in which it is configured.
Installing the plugin consists of creating its custom execution in Pandora FMS. Every certain configurable time interval, the plugin will run and display the updated modules.
Life-cycle of a plugin
Planning a plugin
When developing a plugin, it is important to correctly plan its development taking into account some aspects.
What problem does the plugin solve?
You should be able to answer these questions in a first step in plugin planning:
- What is the purpose of the plugin?
- What are the use cases that your plugin will address?
It is important to be clear about what solution you intend to achieve with the plugin. It could be monitoring a service of interest, managing to unify all data in Pandora FMS which can be an advantage in time or costs, or it can also be automating a process, such as a plugin that reads emails and with which an alarm can be activated when a certain message arrives.
Plugins seek to solve a need or make interaction, processing and data display easier.
How will the plugin retrieve data?
The main utility of a plugin is to retrieve data, from a service, application, database… and be able to display this data in Pandora FMS. But how can data be retrieved from the required service?
This, undoubtedly, depends on the technology or service that is intended to be exploited with the plugin, so it is necessary to carry out a preliminary investigation on the chosen service, to find out the feasibility of the plugin and whether it is possible to create a testing environment to test it.
Usually these services have some way to get the monitoring statistics, that way usually varies depending on the service. Often they have an API or a CLI with which to be able to process the required data and be able to show them with the plugin.
In some cases there are libraries that the community or the company that created the technology or service itself created to make interaction much easier with data from their services.
Do users need permission to get data?
It is likely that when retrieving data from a service or technology, it is necessary to have an account that needs certain permissions to interact with the data, or that it is necessary to make some previous configurations in the environment before this data can be retrieved.
Generally speaking, these requirements are specified in the service or technology documentation itself.
It is important to keep clearly in mind what is necessary and what the requirements are to be able to retrieve data from that service and leave them detailed in the plugin documentation.
Are data collected remotely or locally?
Performance statistics may be retrieved by API remotely, either through some library, CLI, or by API with HTTP calls… or this data may only be retrieved internally or locally by commands or because it uses its own technology. Depending on the case, the plugin execution will change and be different.
A plugin that can get data remotely, can run with the plugin server, as it does not need to be present on the service machine to get data.
There are certain plugins that can only be run through the software agent since they need to be on the same system as the service from which you may want to get data in order to get them.
How do you wish to see data?
When defining how to display the plugin data on Pandora FMS console, it is important to specify how you want to display this data.
Usually these data will be displayed following an agent and module structure, so it is important to define this structure correctly to then be able to see the information as easy as possible, so that it is not confusing, something that can be difficult to achieve in plugins that process lots of data or that monitor many “elements”, such as the case of having many databases, virtual machines, etc.
Within the plugin you may include options to customize agent or module names, or add some kind of prefix to their name to make them more visible and distinguishable.
Plugin requirements and dependencies
Depending on the technologies used in the plugin, dependency installation may be necessary for its correct operation. These can be libraries of the language used that you imported into the plugin to perform some function or the language used itself.
If the plugin is written in Python 3, it will be necessary to have python3
installed in the machine you wish to use the plugin in, which could be a great obstacle for possible potential users of that plugin.
One option, for plugins created in Python is to provide a requirements.txt
file next to the plugin that may include all the dependencies used by the plugin, so installing this file will automatically install all the necessary dependencies.
Example of the plugin requirements.txt
file, specifically that of remote MongoDB.
dnspython==2.1.0 pymongo==3.12.0
You may see how the file includes two libraries that it is necessary to keep installed on the system in order to launch it (in case it is not a compiled plugin).
The file can be written manually, but you may also generate a requirements.txt
file that includes all the installed virtual environment dependencies with the pip freeze
command.
pip freeze> requirements.txt
You may copy the requirements file to the environment in which you wish to install the dependencies and run the following command to install them:
pip install -r requirements.txt
Plugin Compilation
One way to solve dependency problems with plugins is to create executables that already come with all the dependencies installed, this is an ideal solution for perl plugins and for Python plugins.
In the case of Python, to create executables, the pyinstaller
library is available:
It can be installed with the following command:
pip install pyinstaller
Once installed, the following command can be used to create a binary of the plugin in a file:
GNU/Linux:
pyinstaller –onefile < plugin_name >.py
MS Windows:
python3 -m PyInstaller –onefile <plugin_name>.py
A folder called dist
will be generated with the binary inside.
It may be the case that a plugin that was compiled on one operating system does not work on another, it is recommended to compile the plugins in Rocky Linux 7, since the plugins compiled on this system usually work on all other GNU/Linux operating systems.
With binaries created in Fedora and Ubuntu we have been able to check that in other systems a dependency error is generated.
Developing a plugin
It is important to be clear about which tools and technologies will be used in the plugin's development.
Development tools
Plugins are scripts that integrate data or an extra feature in Pandora FMS, they are still small programs, so to develop them it is necessary to have a framework or a code editor such as Visual Studio Code.
In turn, tools such as GitHub or GitLab may help preserve and maintain the code of the plugins created.
Programming languages
For plugin development, it is necessary to use a programming language, Pandora FMS supports any type of language, as long as it displays the data in XML format, Pandora FMS will be able to understand and display them in your console. To that end, follow a label structure with the XML that includes agents, modules and their attributes.
Usually the scripting languages most commonly used in Pandora FMS plugins are Python, Perl, BASH and Powershell, the first two being probably the most complete ones.
Python and perl have a tool developed by Pandora FMS that makes plugin creation easier called Plugin Tools, this tool has a lot of features conceived to make plugin creation easier as well as automate it, so it can be a decisive advantage when choosing the right language.
Useful tools for building test environments
For plugin development it is usually necessary a testing environment, either an installation of the service that you wish to monitor, an account, etc. Two useful technologies for environment creation due to their speed and simplicity are docker and vagrant, since they allow generating environments with only a few commands or small configurations, although of course, it is necessary to have a solution in those projects of the service that you wish to test.
XML
In order for Pandora FMS to consume the data it receives from the plugin in order to display it, it is necessary for those data to be translated into XML format.
Knowing the format of Pandora FMS data XML can help you improve plugins, create custom agents with them, or just send custom XML files to Pandora FMS data server.
Like any XML document, the data file should start with an XML declaration:
<?xml version='1.0' encoding='UTF-8'?>
However, although the plugins and their data is based on XML, only the agent plugins will generate an XML in a terminal execution, server plugins only show a simple data, like one, which will be the value that will contain the module that activates it, so the most normal thing in these cases is that it shows 1
if it works and 0
if, on the contrary, it returned some kind of error.
Agents and modules
The data that the plugin collects may be displayed in Pandora FMS through agents and modules, so it is important to outline the way in which you may want to display data. For example, each agent could be a database to be monitored, with modules representing its information.
The XML structures of agents and modules have different attributes for configuring them.
Agents
The element agent_data
, which defines the agent that sends the data, supports the following attributes:
description
: Agent description.group
: Name of the group the agent belongs to (it must exist in Pandora FMS database). If left empty and there is no default configured group on the server, the agent will not be created.os_name
: Name of the operating system the agent runs in (it must exist in Pandora FMS database).os_version
: Free string describing the version of the operating system.interval
: Agent interval (in seconds).version
: String with agent version.timestamp
: Timestamp indicating when the XML was generated (YYYY/MM/DD HH:MM:SS
).agent_name
: Agent name.timezone_offset
: Offset added to the timestamp (in hours). Useful if working with UTC.address
: Agent IP address (or FQDN).parent_agent_name
: Name of the agent's parent.agent_alias
: Agent alias.agent_mode
: Agent working mode (0
: Normal mode,1
: Learning mode,2
: Autodisable mode) .secondary_groups
: Secondary groups added to the agent.custom_id
: Agent custom ID.url_address
: Agent login URL.
XML heading example
<agent_data description= group= os_name='linux' os_version='Ubuntu 10.10' interval='30' version='3.2(Build 101227)' timestamp='2011/04/20 12:24:03' agent_name='foo' timezone_offset='0' parent_agent_name='too' address='192.168.1.51' custom_id='BS4884' url_address='http://mylocalhost:8080'>
Modules
A module element is needed for each module
, and the following elements may be nested to define the module:
- name: Module name.
- description: Module description.
- tags: Tags associated with the module.
- type: Module type (it must exist in Pandora FMS database).
- data: Module data.
- max: Maximum module value.
- min: Minimum module value.
- post_process: Post-processing value.
- module_interval: Module interval (interval in seconds /agent interval).
- min_critical: Minimum value for critical status.
- max_critical: Maximum value for critical status.
- min_warning: Minimum value for alert status.
- max_warning: Maximum value for alert status.
- disabled: Disable (0) or enable the module. Disabled modules are not processed.
- min_ff_event: FF threshold (see Flip-Flop).
- status: Module status (NORMAL, WARNING or CRITICAL). Critical and alert status limits are ignored if the status is specified.
- datalist: It sends the module data in datalist format (one database entry for each of the values received) [0/1].
- unit: Module unit. It supports
_timeticks_
macro to transform data in timeticks format todd/hh/mm/ss
. - timestamp: It sets a timestamp on the data received from the module (to use timestamp in modules they must be in a datalist block, as shown in the examples below).
- module_group: Group of modules to which the module will be added.
- custom_id: Module custom ID.
- str_warning: Warning threshold for string modules.
- str_critical: Critical threshold for string modules.
- critical_instructions: Critical module instructions.
- warning_instructions: Warning module instructions.
- unknown_instructions: Module unknown instructions.
- critical_inverse: It activates the inverse interval at the module's critical threshold. [0/1].
- warning_inverse: It activates the inverse interval at the module's warning threshold. [0/1].
- quiet: It activates the module's Quiet mode [0/1].
- module_ff_interval: It specifies an FF Range value of the module.
- alert_template: It associates an alert template to the module.
- crontab: It specifies a module crontab.
- min_ff_event_normal: FF threshold value when switching to NORMAL status.
- min_ff_event_warning: FF threshold value when switching to WARNING status.
- min_ff_event_critical: FF threshold value when switching to CRITICAL status.
- ff_timeout: FlipFlop timeout value.
- each_ff: It enables the “Change each status” option.
- module_parent: Module name in the same agent that will be the parent of this module.
- ff_type: It activates the Keep counters of the FF threshold. [0/1].
- min_warning_forced: It forces min_warning to the new specified value even if the module exists, it takes precedence over min_warning.
- max_warning_forced: It forces max_warning to the new specified value even if the module exists, it takes precedence over max_warning.
- min_critical_forced: It forces min_critical to the new specified value even if the module exists, it takes precedence over min_critical.
- max_critical_forced: It forces max_critical to the new specified value even if the module exists, it takes precedence over max_critical.
- str_warning_forced: It forces str_warning to the new specified value even if the module exists, it takes precedence over str_warning.
- str_critical_forced: It forces str_critical to the new specified value even if the module exists, it takes precedence over str_critical.
Module elements
A module must have at least one name, type and data element.
<module> <name>CPU</name> <description>CPU usage percentage</description> <type>generic_data</type> <data>21</data> </module>
There can be any number of elements in an XML data file.
Do not forget to close the tag agent_data
!
List type modules
There are also list modules, which instead of having only one value may contain several, these are useful for string values. The datalist tag should be used in this type of modules as you see in the following example:
<module> <type>async_string</type> <datalist> <data><value><![CDATA[xxxxx]]></value></data> <data><value><![CDATA[yyyyy]]></value></data> <data><value><![CDATA[zzzzz]]></value></data> </datalist> </module>
Timestamp in modules
A timestamp can be specified for each value:
<module> <type>async_string</type> <datalist> <data> <value><![CDATA[xxxxx]]></value> <timestamp>1970-01-01 00:00:00</timestamp> </data> <data> <value><![CDATA[yyyyy]]></value> <timestamp>1970-01-01 00:00:01</timestamp> </data> <data> <value><![CDATA[zzzzz]]></value> <timestamp>1970-01-01 00:00:02</timestamp> </data> </datalist> </module>
Thresholds and units
More examples that include the use of thresholds and units:
<module> <name><![CDATA[Cache mem free]]></name> <description><![CDATA[Free cache memory in MB]]></description> <tags>tag</tags> <type>generic_data</type> <module_interval>1</module_interval> <min_critical>100</min_critical> <max_critical>499</max_critical> <min_warning>500</min_warning> <max_warning>600</max_warning> <unit><![CDATA[MB]]></unit> <data><![CDATA[3866]]></data> </module> <module> <name><![CDATA[Load Average]]></name> <description><![CDATA[Average process in CPU (Last minute) ]]></description> <tags>tag</tags> <type>generic_data</type> <module_interval>1</module_interval> <data><![CDATA[1.89]]></data> </module>
Plugintools
Pandora FMS has a tool called Plugintools, available for the Perl and Python programming languages that makes plugin development easier, since it has built-in features that make most of the processes necessary for creating a plugin easier:
- Agent creation.
- Module creation.
- Send files through Tentacle.
- Read configuration files.
Plugintools Python version
Plugintools Perl version
Parameters and configuration
A utility to consider, that is usually quite useful when interacting with a plugin, is the parameters and configuration files, since these give the option of being able to customize the plugin's execution, making it possible to create different executions. With them you may define data that will always be variable such as the service IP or the credentials to be targeted or be able to customize the name of the modules or agents among other things. Using parameters for plugin configuration has advantages and disadvantages over using configuration files, since you avoid using more files for plugin use, but plugin configuration can surely be done faster with a configuration file, it is important to evaluate which option is best for each plugin.
Plugin help
Another option that is usually quite useful in a plugin, is to include a parameter as its help option, to show all the plugin options and parameters and how to configure it. It is like a small digital documentation about the plugin included in its software.
Pandora FMS plugin settings
The plugin settings may vary depending on whether this is an agent or server plugin.
Server plugins
In order to monitor from Pandora FMS with a server agent plugin, go to the “plugins” section within the servers menu.
Click “Add”. Give it the name and description of your choice.
As a command you should enter the execution with the plugin path.
The recommended path for using server plugins is:
/usr/share/pandora_server/util/plugin/
The execution with the plugin path must be entered as a command:
In plugin parameters, enter them followed by the macro _field_
.
–SERVER
–SUBJECT
–BODY
Once done, click “create”.
Once the previous steps have been completed, call the plugin. Go to the agent view and create a plugin module. A name must be given, and in the “plugin” section, the one you just configured is added.
Once done, click “create”.
If the module is shown with 1
, it means that it is running properly and an agent containing the modules was created.
Agent plugin
In order to monitor from Pandora FMS with an agent plugin, call it from the software agent .conf
file found at the following path, in GNU/Linux:
/etc/pandora/pandora_agent.conf
The execution on the last conf line may be created with the module_plugin
command, followed by the execution command.
Example of a possible plugin execution:
module_plugin /etc/pandora/plugins/MyMonitor.pl /etc/pandora/plugins/MyMonitor.conf
This can also be done from the console if remote configuration is enabled. For example:
Displaying the plugin in Pandora FMS
The display of the plugin data is usually done from the agents view. The data structure is usually defined by agents and modules, so it is normal for the plugin to create agents and modules within them, so these data may be displayed in the view menu of the agent itself.
In many plugins, it could be the case that many agents are created, such as the Xenserver plugin that creates an agent for each virtual server machine, but luckily you may define a prefix for the agents, in this case for example the prefix xen-
could be used, so when viewing the agents, you may see that some have that structure in the name and you will know that those agents come from that particular plugin.
PSPZ2
A pspz2 file is a zip compressed file made up of two files, the plugin and a plugin_definition.ini
file that contains the plugin and module specification.
This file format is very useful when packaging plugins, as it simplifies their installation. Using this format, plugins can be installed more quickly in Pandora FMS console from the “plugins registration” section.
Example of plugins_definition.ini
of a plugin:
[plugin_definition] name = Pandora Azure Storage description = "Take data from azure storage" timeout = 20 filename = pandora_azure execution_command = execution_postcommand = parameters = -c _field1_ –agent_name _field2_ -g _field3_ plugin_type = 0 total_modules_provided = 0 total_macros_provided = 8 [macro_1] hide = 0 description = "Conf path (obligatory)" help = "Path conf" value = [macro_2] hide = 0 description = "Agent name (optional)" help = "Name of the agent" value = _agentname_ [macro_3] hide = 0 description = "group (optional)" help = "Pandora FMS Target Group " value =
filename: It should have the same name as the script included in file .pspz
, previously named as < script_file >
. In this example it is a shell script ( .sh
format) named ssh_pandoraplugin.sh
.
plugin_type: 0
for a Pandora FMS standard plugin, and 1
for a Nagios plugin.
total_modules_provided: It specifies how many modules are defined in the following sections of the .ini
file. Set at least one (for use in an example at least).
execution_command: If it is used, it must be entered before the script. It could be an interpreter, such as java -jar
. Therefore, the plugin will be called for execution, from Pandora FMS Plugin Server, with the following code: java -jar < plugin_path/ plugin_filename
.
execution_postcommand: If used, it defines the additional parameters transmitted to the plugin after < plugin_filename >
, which is not visible to the user.
total_macros_provided: It defines the number of dynamic macros the plugin has.
macro__value: It defines the value for that Module using that dynamic macro, if it does not exist, the default value is taken.
And it must create a section for each dynamic macro, for example:
[macro_<N>] hide = 0 description = <your_description> help = <text_help> value = <your_value>
Compatibility
It is important for the plugin to have as much compatibility as possible. Certain plugins are unique to services that can only be exploited on a given operating system, such as MS Windows®. But within the inevitable limitations, it is important to give the plugin a compatibility that covers as many scenarios as possible.
Certain operating systems have packages that do not exist in others, which can lead to errors in the execution of a compiled plugin, so it is advisable to compile the plugins on a machine with Rocky Linux 7 operating system that has all the necessary plugin dependencies installed.
Error control
Having good error control can help maintain the plugin over time, as it can help detect potential future errors in the plugin and locate them more quickly.
It can also help to detect what the error is accurately, since without error control, in certain cases, the error output may be too generic and it may be difficult to figure out what the problem is.
Plugin tests and validation
Once the plugin is developed, it is suitable to perform tests in environments to check its operation, in fact it would be great to be able to test it in more than one test environment.
A good testing process can help to solve possible errors and to make the plugin's operation more solid over time, as it is usually said, better safe than sorry.
Plugin launching
When publishing the plugin, it is important to take certain aspects into account.
Plugin documentation
Using some plugins could be at first difficult to understand. Some may have several options and it can be a bit hard to understand them.
Good documentation may help you understand it, it can even be useful for plugin creators themselves in the future, to help them remember certain things about the plugin that they may have forgotten over time.
Pandora FMS has a system of online quick guides that makes documentation maintenance easier, which can be accessed from the following link:
The alternative to the documentation in quick-guide format is the PDF format.
Upload a plugin to the library
The process when uploading a plugin to Pandora FMS library is very simple. Just access the “upload new module” section within “my plugins” section of the library.
Once all the sections of the entry have been configured, such as the title, a description of the plugin, the compressed plugin in zip format, the documentation, categories and tags, the plugin can be published by clicking on submit.
All plugins uploaded to the library are reviewed and need a review time, before their final release.
Once the plugin is published, it will appear in the “latest uploads” section:
Good practices to help review and maintain a plugin
Some good practices can help decrease the time spent on tasks, prevent and circumvent common errors during the different stages of the plugin creation process and plugin maintenance over time, and make their review easier. These can be:
- Leaving a good previous configuration well documented, in case it is necessary to make some previous configurations on the system on the plugin itself.
- Documenting an example of actual execution of the plugin that helps users visualize its use.
- Writing comments in the plugin code can help understand it better or faster.
- Prioritizing code readability. The more complex it is, the more time and resources will be needed to deal with it.
- Testing your code. It is important to test the plugin's operation to verify that everything is fine. Finding an error in time and fixing it will avoid problems in the future.