{"id":16117288,"url":"https://github.com/nickbabcock/collectd-rust-plugin","last_synced_at":"2025-06-20T18:10:57.237Z","repository":{"id":24445800,"uuid":"101583331","full_name":"nickbabcock/collectd-rust-plugin","owner":"nickbabcock","description":"Write a low-cost, ergonomic plugin for collectd","archived":false,"fork":false,"pushed_at":"2024-10-16T10:38:08.000Z","size":646,"stargazers_count":31,"open_issues_count":5,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-18T19:03:56.691Z","etag":null,"topics":["bindgen","collectd","collectd-plugin","ffi","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/collectd-plugin","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickbabcock.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-27T22:09:24.000Z","updated_at":"2025-01-09T17:27:12.000Z","dependencies_parsed_at":"2024-01-08T02:46:03.775Z","dependency_job_id":"929d8340-1e93-4408-a6f0-2ebd17254676","html_url":"https://github.com/nickbabcock/collectd-rust-plugin","commit_stats":{"total_commits":579,"total_committers":6,"mean_commits":96.5,"dds":0.03799654576856648,"last_synced_commit":"a9f5eb67641be4d73e3b35bc544d2b1bb9fb0047"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/nickbabcock/collectd-rust-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2Fcollectd-rust-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2Fcollectd-rust-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2Fcollectd-rust-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2Fcollectd-rust-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickbabcock","download_url":"https://codeload.github.com/nickbabcock/collectd-rust-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2Fcollectd-rust-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260993956,"owners_count":23094275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bindgen","collectd","collectd-plugin","ffi","rust"],"created_at":"2024-10-09T20:43:51.162Z","updated_at":"2025-06-20T18:10:52.225Z","avatar_url":"https://github.com/nickbabcock.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![ci](https://github.com/nickbabcock/collectd-rust-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/nickbabcock/collectd-rust-plugin/actions/workflows/ci.yml) [![](https://docs.rs/collectd-plugin/badge.svg)](https://docs.rs/collectd-plugin) [![Version](https://img.shields.io/crates/v/collectd-plugin.svg?style=flat-square)](https://crates.io/crates/collectd-plugin)\n\n# Write a Collectd Plugin in Rust\n\n[Collectd](https://collectd.org/) is a ubiquitous system statistics collection\ndaemon. This Rust library leverages collectd's ability to dynamically load\nplugins and creates an ergonomic, yet extremely low cost abstraction API to\ninterface with collectd. Works with collectd 5.7+.\n\nFeatures:\n\n- No unnecessary allocations when submitting / receiving values, logging\n- Register multiple plugin instances\n- Automatic deserialization of plugin configs via [Serde](https://github.com/serde-rs/serde) (can opt-out)\n- Deployment: compile against collectd version and scp to server\n- Referenced Rust libraries are statically linked\n- Help writing thread safe plugins thanks to the Rust compiler\n\n## Usage\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\ncollectd-plugin = \"0.15.0\"\n```\n\n[Serde](https://github.com/serde-rs/serde) support is enabled by default for configuration parsing.\n\n## Quickstart\n\n[See what to add to your project's Cargo file](#to-build)\n\nBelow is a complete plugin that dummy reports [load](https://en.wikipedia.org/wiki/Load_(computing)) values to collectd, as it registers a `READ` hook. For an implementation that reimplements collectd's own load plugin, see [examples/load](https://github.com/nickbabcock/collectd-rust-plugin/tree/master/examples/load.rs)\n\n```rust\nuse collectd_plugin::{\n    collectd_plugin, ConfigItem, Plugin, PluginCapabilities, PluginManager, PluginRegistration,\n    Value, ValueListBuilder,\n};\nuse std::error;\n\n#[derive(Default)]\nstruct MyPlugin;\n\n// A manager decides the name of the family of plugins and also registers one or more plugins based\n// on collectd's configuration files\nimpl PluginManager for MyPlugin {\n    // A plugin needs a unique name to be referenced by collectd\n    fn name() -\u003e \u0026'static str {\n        \"myplugin\"\n    }\n\n    // Our plugin might have configuration section in collectd.conf, which will be passed here if\n    // present. Our contrived plugin doesn't care about configuration so it returns only a single\n    // plugin (itself).\n    fn plugins(\n        _config: Option\u003c\u0026[ConfigItem\u003c'_\u003e]\u003e,\n    ) -\u003e Result\u003cPluginRegistration, Box\u003cdyn error::Error\u003e\u003e {\n        Ok(PluginRegistration::Single(Box::new(MyPlugin)))\n    }\n}\n\nimpl Plugin for MyPlugin {\n    // We define that our plugin will only be reporting / submitting values to writers\n    fn capabilities(\u0026self) -\u003e PluginCapabilities {\n        PluginCapabilities::READ\n    }\n\n    fn read_values(\u0026self) -\u003e Result\u003c(), Box\u003cdyn error::Error\u003e\u003e {\n        // Create a list of values to submit to collectd. We'll be sending in a vector representing the\n        // \"load\" type. Short-term load is first (15.0) followed by mid-term and long-term. The number\n        // of values that you submit at a time depends on types.db in collectd configurations\n        let values = vec![Value::Gauge(15.0), Value::Gauge(10.0), Value::Gauge(12.0)];\n\n        // Submit our values to collectd. A plugin can submit any number of times.\n        ValueListBuilder::new(Self::name(), \"load\")\n            .values(\u0026values)\n            .submit()?;\n\n        Ok(())\n    }\n}\n\n// We pass in our plugin manager type\ncollectd_plugin!(MyPlugin);\n```\n\n## Motivation\n\nThere are five main ways to extend collectd:\n\n- Write plugin against the C api: `\u003ccollectd/core/daemon/plugin.h\u003e`\n- Write plugin for [collectd-python](https://collectd.org/documentation/manpages/collectd-python.5.shtml)\n- Write plugin for [collectd-java](https://collectd.org/wiki/index.php/Plugin:Java)\n- Write a cli for the [exec plugin](https://collectd.org/documentation/manpages/collectd-exec.5.shtml)\n- Write a service that [writes to a unix socket](https://collectd.org/wiki/index.php/Plugin:UnixSock)\n\nAnd my thoughts:\n\n- I'm not confident enough to write C without leaks and there isn't a great package manager for C.\n- 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.\n- The exec plugin is costly as it creates a new process for every collection\n- 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.\n\nRust's combination of ecosystem, package manager, C ffi, single file dynamic library, and optimized code made it seem like a natural choice.\n\n## To Build\n\nTo ensure a successful build, adapt the below to your project's Cargo file.\n\n```toml\n[lib]\ncrate-type = [\"cdylib\"]\nname = \"\u003cyour plugin name\u003e\"\n\n[features]\nbindgen = [\"collectd-plugin/bindgen\"]\ndefault = []\n```\n\n- `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:\n  - Specify the `bindgen` feature with `COLLECTD_PATH` pointing at the [root git directory for collectd](https://github.com/collectd/collectd)\n    - The `bindgen` feature also works if `collectd-dev` is installed\n  - `COLLECTD_VERSION` may be used in the future when `collectd-rust-plugin` reintroduces support for compiling against different collectd versions that are not API-compatible\n  - When collectd is present on the system, the version is derived from executing `collectd -h`\n- collectd expects plugins to not be prefixed with `lib`, so `cp target/debug/libmyplugin.so /usr/lib/collectd/myplugin.so`\n- Add `LoadPlugin myplugin` to collectd.conf\n\n## Plugin Configuration\n\nThe load plugin in\n[examples/load](https://github.com/nickbabcock/collectd-rust-plugin/tree/master/examples/load.rs)\ndemonstrates how to expose configuration values to collectd.\n\n```xml\n# In this example configuration we provide short and long term load and leave\n# Mid to the default value. Yes, this is very much contrived\n\u003cPlugin loadrust\u003e\n    ReportRelative true\n\u003c/Plugin\u003e\n```\n\n## Benchmarking Overhead\n\nTo measure the overhead of adapting collectd's datatypes when writing and reporting values:\n\n```bash\ncargo bench --features stub\n```\n\nIf you'd like to use the timings on my machine:\n\n- 60ns to create and submit a `ValueListBuilder`\n- 130ns to create a `ValueList` for plugins that write values\n\nUnless 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.\n\n## Plugins\n\nDo you use collectd-rust-plugin? Feel free to add your plugin to the list.\n\n- [pg-collectd](https://github.com/nickbabcock/pg-collectd): An alternative and opinionated postgres collectd writer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickbabcock%2Fcollectd-rust-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickbabcock%2Fcollectd-rust-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickbabcock%2Fcollectd-rust-plugin/lists"}