Crates.io | collectd-plugin |
lib.rs | collectd-plugin |
version | 0.15.0 |
source | src |
created_at | 2017-11-30 23:37:34.683716 |
updated_at | 2024-08-06 11:44:54.644381 |
description | Provides ergonomic API ontop of collectd's C interface and macro for defining plugins easier |
homepage | |
repository | https://github.com/nickbabcock/collectd-rust-plugin |
max_upload_size | |
id | 41167 |
size | 246,134 |
Collectd is a ubiquitous system statistics collection daemon. This Rust library leverages collectd's ability to dynamically load plugins and creates an ergonomic, yet extremely low cost abstraction API to interface with collectd. Works with collectd 5.7+.
Features:
Add to your Cargo.toml
:
[dependencies]
collectd-plugin = "0.15.0"
Serde support is enabled by default for configuration parsing.
See what to add to your project's Cargo file
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 examples/load
use collectd_plugin::{
collectd_plugin, ConfigItem, Plugin, PluginCapabilities, PluginManager, PluginRegistration,
Value, ValueListBuilder,
};
use std::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, Box<dyn error::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<(), Box<dyn error::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()?;
Ok(())
}
}
// We pass in our plugin manager type
collectd_plugin!(MyPlugin);
There are five main ways to extend collectd:
<collectd/core/daemon/plugin.h>
And my thoughts:
Rust's combination of ecosystem, package manager, C ffi, single file dynamic library, and optimized code made it seem like a natural choice.
To ensure a successful build, adapt the below to your project's Cargo file.
[lib]
crate-type = ["cdylib"]
name = "<your plugin name>"
[features]
bindgen = ["collectd-plugin/bindgen"]
default = []
collectd-rust-plugin
assumes a 5.7
-compatible API (5.7
works up to at least 5.12
). This can be configured via any of the following:
bindgen
feature with COLLECTD_PATH
pointing at the root git directory for collectd
bindgen
feature also works if collectd-dev
is installedCOLLECTD_VERSION
may be used in the future when collectd-rust-plugin
reintroduces support for compiling against different collectd versions that are not API-compatiblecollectd -h
lib
, so cp target/debug/libmyplugin.so /usr/lib/collectd/myplugin.so
LoadPlugin myplugin
to collectd.confThe load plugin in examples/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
<Plugin loadrust>
ReportRelative true
</Plugin>
To measure the overhead of adapting collectd's datatypes when writing and reporting values:
cargo bench --features stub
If you'd like to use the timings on my machine:
ValueListBuilder
ValueList
for plugins that write valuesUnless you are reporting or writing millions of metrics every interval (in which case you'll most likely hit an earlier bottleneck), you'll be fine.
Do you use collectd-rust-plugin? Feel free to add your plugin to the list.