Crate collectd_plugin

source ·
Expand description

Collectd is a ubiquitous system statistics collection daemon. collectd_plugin leverages Collectd’s ability to dynamically load plugins and creates an ergonomic, yet extremely low cost abstraction API to interface with Collectd.

Features:

  • No unnecessary allocations when submitting / receiving values, logging
  • Register multiple plugin instances
  • Automatic deserialization of plugin configs via Serde (optional) feature
  • Deployment: compile against collectd version and scp to server
  • Referenced Rust libraries are statically linked

Usage

Add to your Cargo.toml:

[dependencies]
collectd-plugin = "0.8.1"

Serde support is enabled by default for configuration parsing.

Then put this in your crate root:

extern crate collectd_plugin;

Rust 1.20 or later is needed to build.

This repo is tested on the following:

  • Collectd 5.4 (Ubuntu 14.04)
  • Collectd 5.5 (Ubuntu 16.04)
  • Collectd 5.7 (and above) (Ubuntu 18.04)

Quickstart

Below is a complete plugin that dummy reports load values to collectd, as it registers a READ hook. For an implementation that reimplements Collectd’s own load plugin, see plugins/load

#[macro_use]
extern crate collectd_plugin;
extern crate failure;

use collectd_plugin::{
    ConfigItem, Plugin, PluginCapabilities, PluginManager, PluginRegistration, Value,
    ValueListBuilder,
};
use failure::Error;

#[derive(Default)]
struct MyPlugin;

// A manager decides the name of the family of plugins and also registers one or more plugins based
// on collectd's configuration files
impl PluginManager for MyPlugin {
    // A plugin needs a unique name to be referenced by collectd
    fn name() -> &'static str {
        "myplugin"
    }

    // Our plugin might have configuration section in collectd.conf, which will be passed here if
    // present. Our contrived plugin doesn't care about configuration so it returns only a single
    // plugin (itself).
    fn plugins(_config: Option<&[ConfigItem]>) -> Result<PluginRegistration, Error> {
        Ok(PluginRegistration::Single(Box::new(MyPlugin)))
    }
}

impl Plugin for MyPlugin {
    // We define that our plugin will only be reporting / submitting values to writers
    fn capabilities(&self) -> PluginCapabilities {
        PluginCapabilities::READ
    }

    fn read_values(&self) -> Result<(), Error> {
        // Create a list of values to submit to collectd. We'll be sending in a vector representing the
        // "load" type. Short-term load is first (15.0) followed by mid-term and long-term. The number
        // of values that you submit at a time depends on types.db in collectd configurations
        let values = vec![Value::Gauge(15.0), Value::Gauge(10.0), Value::Gauge(12.0)];

        // Submit our values to collectd. A plugin can submit any number of times.
        ValueListBuilder::new(Self::name(), "load")
            .values(&values)
            .submit()
    }
}

// We pass in our plugin manager type
collectd_plugin!(MyPlugin);

Modules

Macros

A simple wrapper around the collectd’s plugin_log, which in turn wraps vsnprintf.
Sets up all the ffi entry points that collectd expects when given a PluginManager.

Structs

CdTime allows for ergonomic interop between collectd’s cdtime_t and chrono’s Duration and DateTime. The single field represents epoch nanoseconds.
Bridges the gap between collectd and rust logging. Terminology and filters methods found here are from env_logger.
Parsed key, values, children objects from the Collectd config.
Bitflags of capabilities that a plugin advertises to collectd.
Bitflags of capabilities that a plugin manager advertises to collectd
Contains values and metadata that collectd has collected from plugins
Creates a value list to report values to collectd.
Name and value of a reported metric

Enums

Errors that occur when converting Rust’s text data to a format collectd expects
A parsed value from the Collectd config
The available levels that collectd exposes to log messages.
How many instances of the plugin will be registered
Errors that occur when submitting values to collectd
The value that a plugin reports can be any one of the following types

Traits

An individual plugin that is capable of reporting values to collectd, receiving values from other plugins, or logging messages. A plugin must implement Sync + Send as collectd could be sending values to be written or logged concurrently. The Rust compiler will ensure that everything not thread safe is wrapped in a Mutex (or another compatible datastructure)
Defines the entry point for a collectd plugin. Based on collectd’s configuration, a PluginManager will register any number of plugins (or return an error)

Functions

Sends message and log level to collectd. This bypasses any configuration setup via CollectdLoggerBuilder, so collectd configuration soley determines if a level is logged and where it is delivered. Messages that are too long are truncated (1024 was the max length as of collectd-5.7).
Returns if the string is empty or not
Turns a fixed size character array into string slice, if possible
Convert epoch nanoseconds into collectd’s 2-30 second resolution