A Collectd Plugin Written in Rust
Collectd gathers system and application metrics and stores the values in any
manner. Since Collectd provides a plugin API, this collectd_plugin overlays a
ergonomic, yet extremely low cost abstractions to interface with Collectd.
Usage
Put this in your Cargo.toml:
[]
= "0.3"
Or, if you want Serde support, include features like this:
[]
= { = "0.3", = ["serde"] }
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 (Ubuntu 17.04)
Quickstart
Below is a complete plugin that dummy reports load values to collectd, as it registers a READ hook. For an implementation has the same behavior as Collectd's own load plugin, see plugins/load
extern crate collectd_plugin;
extern crate failure;
use ;
use Error;
;
// A manager decides the name of the family of plugins and also registers one or more plugins based
// on collectd's configuration files
// We pass in our plugin manager type
collectd_plugin!;
Motivation
There are four main ways to extend collectd:
- Write plugin against the C api:
<collectd/core/daemon/plugin.h> - Write plugin for collectd-python
- Write plugin for collectd-java
- Write a cli for the exec plugin
- Write a service that writes to a unix socket
And my thoughts:
- I'm not confident enough to write C without leaks and there isn't a great package manager for C.
- Python and Java aren't self contained, aren't necessarily deployed on the server, are more heavy weight, and I suspect that maintenance plays second fiddle to the C api.
- The exec plugin is costly as it creates a new process for every collection
- Depending on the circumstances, writing to a unix socket could be good fit, but I enjoy the ease of deployment, and the collectd integration -- there's no need to re-invent logging scheme, configuration, and system init files.
Rust's combination of ecosystem, package manager, C ffi, single file dynamic library, and optimized code made it seem like a natural choice.
To Build
To ensure a successful build, the following steps are needed:
- When building, you must supply the collectd version you'll be deploying:
cargo build --features collectd-54cargo build --features collectd-55cargo build --features collectd-57
- Your project crate type must be
cdylib - If you want to use
bindgento generate the ffi functions, use thebindgenfeature (still alongside the desired collectd version). Make sure you have an appropriate version of clang installed andcollectd-dev - Collectd expects plugins to not be prefixed with
lib, socp target/debug/libmyplugin.so /usr/lib/collectd/myplugin.so - Add
LoadPlugin mypluginto collectd.conf
Plugin Configuration
The load plugin in plugins/load demonstrates how to expose configuration values to Collectd.
# In this example configuration we provide short and long term load and leave
# Mid to the default value. Yes, this is very much contrived
ReportRelative true