#plugin-api #plugin #write #statistics #collection #integration #collectd

sys collectd-plugin

在 collectd 的 C 接口之上提供易于使用的 API,并使用宏简化插件定义

27 个不稳定版本

0.15.0 2024 年 8 月 6 日
0.14.0 2021 年 6 月 15 日
0.13.0 2020 年 5 月 10 日
0.11.0 2019 年 10 月 30 日
0.2.0 2017 年 11 月 30 日

#89 in 操作系统

Download history 34/week @ 2024-04-22 18/week @ 2024-04-29 5/week @ 2024-05-06 7/week @ 2024-05-13 16/week @ 2024-05-20 9/week @ 2024-05-27 23/week @ 2024-06-03 56/week @ 2024-06-10 97/week @ 2024-06-17 43/week @ 2024-06-24 12/week @ 2024-07-01 17/week @ 2024-07-08 4/week @ 2024-07-15 40/week @ 2024-07-22 37/week @ 2024-07-29 152/week @ 2024-08-05

每月 233 次下载

MIT 许可证

170KB
4K SLoC

ci Version

用 Rust 编写 Collectd 插件

Collectd 是一种常见的系统统计收集守护进程。这个 Rust 库利用 collectd 的动态加载插件的能力,创建了一个易于使用且成本极低的抽象 API,用于与 collectd 接口。支持 collectd 5.7 及以上版本。

特性

  • 提交/接收值、记录时无需进行不必要的分配
  • 注册多个插件实例
  • 通过 Serde 自动反序列化插件配置(可选退出)
  • 部署:针对 collectd 版本进行编译,然后通过 scp 传输到服务器
  • 引用的 Rust 库是静态链接的
  • 由于 Rust 编译器的帮助,有助于编写线程安全的插件

用法

添加到您的 Cargo.toml

[dependencies]
collectd-plugin = "0.15.0"

Serde 支持默认启用配置解析。

快速入门

查看要添加到项目 Cargo 文件的内容

以下是一个完整的插件,它作为 负载 值的示例报告到 collectd,因为它注册了一个 READ 钩子。有关重新实现 collectd 自身负载插件的实现,请参阅 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);

动机

扩展 collectd 的主要有五种方式

以及我的想法

  • 我没有足够的信心编写没有泄漏的C代码,而且还没有一个非常好的C包管理器。
  • Python和Java不是自包含的,不一定部署在服务器上,比较重,我怀疑维护工作不如C API重要。
  • exec插件成本高昂,因为它为每个收集项创建一个新的进程。
  • 根据具体情况,写入Unix套接字可能是一个不错的选择,但我喜欢部署的简便性以及collectd的集成——无需重新发明日志方案、配置和系统初始化文件。

Rust的生态系统、包管理器、C ffi、单文件动态库和优化代码使它成为了一个自然的选择。

构建

为确保构建成功,请根据您的项目Cargo文件进行调整。

[lib]
crate-type = ["cdylib"]
name = "<your plugin name>"

[features]
bindgen = ["collectd-plugin/bindgen"]
default = []
  • collectd-rust-plugin假定与5.7-兼容的API(5.7至少适用于5.12)。这可以通过以下方式配置:
    • 使用bindgen特性,将COLLECTD_PATH指向collectd的根git目录
      • 如果安装了collectd-devbindgen特性也将生效
    • 将来,当collectd-rust-plugin重新引入对不兼容API的不同collectd版本的编译支持时,可以使用COLLECTD_VERSION
    • 当系统上存在collectd时,版本是通过执行collectd -h得到的
  • collectd期望插件不以lib为前缀,因此cp target/debug/libmyplugin.so /usr/lib/collectd/myplugin.so
  • LoadPlugin myplugin添加到collectd.conf

插件配置

examples/load中的加载插件演示了如何将配置值公开给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>

基准测试开销

为了衡量在写入和报告值时适配collectd的数据类型时的开销

cargo bench --features stub

如果您想使用我机器上的计时

  • 创建并提交一个ValueListBuilder需要60纳秒
  • 为写入值的插件创建一个ValueList需要130纳秒

除非您在每个时间间隔内报告或写入数百万个指标(在这种情况下,您很可能会遇到早期瓶颈),否则您会没事的。

插件

您使用collectd-rust-plugin吗?请随意将您的插件添加到列表中。

  • pg-collectd:一个替代的、有自己看法的PostgreSQL collectd写入器

依赖

~3.5–6MB
~105K SLoC