Zabbix Code Guidelines

Plugins

Zabbix plugin development guidelines

Plugins provide an option to extend monitoring capabilities of Zabbix. A plugin is a Go package that defines the structure and implements one or several plugin interfaces (Exporter, Collector, Runner, Watcher). To ensure that the plugin meets all the quality requirements, the following guidelines should be used.

Plugins are supported by Zabbix agent 2 only. All plugin configuration parameters are located in the same file as parameters of the agent 2 itself.

By default, plugins are inactive and activated only when a metric is provided by the plugin being monitored.

Plugins are located in the plugin directory tree, grouped by meaning, for example plugins/system/uptime/uptime.go.

Plugin interfaces

The following plugin interfaces are available:

  • plugin.Exporter

Exporter is the simplest interface that performs a poll and returns a value (values), nothing, error. It accepts a preparsed item key, parameters and context. Exporter interface is the only interface that can be accessed concurrently. All other plugin interface access is exclusive and no method can be called when a plugin is already performing some task. Also, there is a limit of 100 maximum concurrent Export() calls per plugin, which can be reduced as necessary for each plugin.

  • plugin.Collector

Collector is used when a plugin needs to collect data at regular intervals. This interface usually is used together with the Exporter interface to export the collected data.

  • plugin.Configurator

Configurator is used to provide plugin its configuration parameters from the agent 2 configuration file.

  • plugin.Runner

Runner interface provides the means of performing some initialization when a plugin is started (activated) and deinitialization when a plugin is stopped (deactivated). For example, a plugin could start/stop some background goroutine by implementing the Runner interface.

  • plugin.Watcher

Watcher allows the plugin to implement its own metric polling, without using the agent's internal scheduler, for example in trap-based plugins.

Implementation steps

A plugin must import the zabbix.com/pkg/plugin package.

import "zabbix.com/pkg/plugin"

A plugin must define the structure and embed the plugin.Base structure.

type Plugin struct {
           plugin.Base
       }
       var impl Plugin

A plugin must implement one or several plugin interfaces.

func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error) {
           if len(params) > 0 {
               p.Debugf("received %d parameters while expected none", len(params))
               return nil, errors.New("Too many parameters")
           }
           return time.Now().Format(time.RFC3339)
       }

A plugin must register itself during initialization.

func init() {
           plugin.RegisterMetrics(&impl, "Time", "system.time", "Returns time string in RFC 3999 format.")
       }

where RegisterMetrics parameters are:

  • Pointer to the plugin implementation
  • Plugin name (upper camel case)
  • Metric #1 name (item key)
  • Metric #1 description (starting with an uppercase character and ending with a dot)
  • Metric #2 name (item key) (optional)
  • Metric #2 description (starting with an uppercase character and ending with a dot) (optional)
  • ...

If logging is necessary the plugin must use the logging functionality provided by plugin.Base (see the example above). It's basically a wrapper around standard logging, but it will prefix log messages with [<plugin name>].

Documentation

The last (but not the least) step of creating a good plugin is to create a Readme file containing the following information:

  • A short description of the plugin.
  • Plugin configuration parameters and steps required for configuring connection with the system being monitored.
  • A list of supported keys.
  • Known limitations/problems (if any).

Existing plugins

To avoid creating duplicate plugins, make sure that a plugin doesn't already exist in Zabbix. Existing plugins are available in Zabbix Git repository

External plugins

External Zabbix agent 2 plugins are supported since Zabbix 6.0.0. Such plugins are kept in a separate repository, but use a shared with Zabbix agent 2 package.

External plugins need to be compiled and built separately. Plugin configuration shall be provided in a separate Zabbix agent 2 configuration file in the same way as it is provided for built-in plugins.

External plugins support the following interfaces: - Exporter (except the ContextProvider parameter) - Runner - Configurator

Watcher and Collector interfaces are not supported.

Zabbix agent 2 connects bidirectionally to the plugins using UNIX sockets on Linux and Named Pipes on Windows.

Several external plugins are available in Zabbix source code and can be used as examples.

Connection protocol

The protocol is based on code, size and data model.

Code

Type Size Comments
Byte 4 Payload type, currently only JSON is supported.

Size

Type Size Comments
Byte 4 Size of the current payload in bytes.

Payload data

Type Size Comments
Byte Defined by the Size field Size of the current payload in bytes.
Payload data definition

Common data

These parameters are present in all requests/responses:

Name Type Comments
id uint32 For requests - the incrementing identifier used to link requests with responses. Unique within a request direction (i.e. from agent to plugin or from plugin to agent).
For responses - ID of the corresponding request.
type uint32 The request type.

Log request

A request sent by a plugin to write a log message into the agent log file.

direction plugin → agent
response no

Parameters specific to log requests:

Name Type Comments
severity uint32 The message severity (log level).
message string The message to log.

Example:

{"id":0,"type":1,"severity":3,"message":"message"}

Register request

A request sent by the agent during the agent startup phase to obtain provided metrics to register a plugin.

direction agent → plugin
response yes

Parameters specific to register requests:

Name Type Comments
version string The protocol version <major>.<minor>

Example:

{"id":1,"type":2,"version":"1.0"}

Register response

Plugin's response to the register request.

direction plugin → agent
response n/a

Parameters specific to register responses:

Name Type Comments
name string The plugin name.
metrics array of strings (optional) The metrics with descriptions as used in the plugin. Returns RegisterMetrics().Absent if error is returned.
interfaces uint32 (optional) The bit mask of plugin's supported interfaces. Absent if error is returned.
error string (optional) An error message returned if a plugin cannot be started. Absent if metrics are returned.

Examples:

{"id":2,"type":3,"metrics":["external.test", "External exporter Test."], "interfaces": 4}

or

{"id":2,"type":3,"error":"error message"}

Start request

A request to execute the Start function of the Runner interface.

direction agent → plugin
response no

The request doesn't have specific parameters, it only contains common data parameters.

Example:

{"id":3,"type":4}

Terminate request

A request sent by the agent to shutdown a plugin.

direction agent → plugin
response no

The request doesn't have specific parameters, it only contains common data parameters.

Example:

{"id":3,"type":5}

Export request

A request to execute the Export function of the Exporter interface.

direction agent → plugin
response no

Parameters specific to export requests:

Name Type Comments
key string The plugin key.
parameters array of strings (optional) The parameters for Export function.

Example:

{"id":4,"type":6,"key":"test.key","parameters":["foo","bar"]}

Export response

Response from the Export function of the Exporter interface.

direction plugin → agent
response n/a

Parameters specific to export responses:

Name Type Comments
value string (optional) Response value from the Export function. Absent if error is returned.
error string (optional) Error message if the Export function has not been executed successfully. Absent if value is returned.

Examples:

{"id":5,"type":7,"value":"response"}

or

{"id":5,"type":7,"error":"error message"}

Configure request

A request to execute the Configure function of the Configurator interface.

direction agent → plugin
response n/a

Parameters specific to configure requests:

Name Type Comments
global_options JSON object JSON object containing global agent configuration options.
private_options JSON object (optional) JSON object containing private plugin configuration options, if provided.

Example:

{"id":6,"type":8,"global_options":{...},"private_options":{...}}

Validate Request

A request to execute the Validate function of the Configurator interface.

direction agent → plugin
response yes

Parameters specific to validate requests:

Name Type Comments
private_options JSON object (optional) JSON object containing private plugin configuration options, if provided.

Example:

{"id":7,"type":9,"private_options":{...}}

Validate response

Response from the Validate function of the Configurator interface.

direction plugin → agent
response n/a

Parameters specific to validate responses:

Name Type Comments
error string (optional) An error message returned if the Validate function is not executed successfully. Absent if executed successfully.

Example:

{"id":8,"type":10}

or

{"id":8,"type":10,"error":"error message"}