1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
//! Config data for a munin plugin
// We do not want to write unsafe code
#![forbid(unsafe_code)]
use log::trace;
use std::{env, path::PathBuf};
/// Plugin configuration.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Config {
/// The name of the plugin.
///
/// Default is "Simple munin plugin in Rust"
pub plugin_name: String,
/// Plugins state directory
///
/// Fallback to /tmp if environment variable MUNIN_PLUGSTATE is
/// not set.
pub plugin_statedir: PathBuf,
/// Does munin support dirtyconfig? (Send data after sending config)
///
/// Checks MUNIN_CAP_DIRTYCONFIG environment variable, if set to 1,
/// this is true, otherwise false.
pub dirtyconfig: bool,
/// Does this plugin need to run in background, continuously fetching data?
///
/// Default to false
pub daemonize: bool,
/// If plugin uses daemonize, whats the pidfile name?
///
/// Defaults to [Config::plugin_statedir] plus "munin-plugin.pid", using
/// [Config::new] will set it to
/// [Config::plugin_statedir]/[Config::plugin_name].pid
pub pidfile: PathBuf,
/// Size of buffer for BufWriter for [MuninPlugin::config](super::MuninPlugin::config).
///
/// Defaults to 8192, but if the plugin outputs huge munin
/// configuration (trivial with multigraph plugins), you may want
/// to increase this.
pub cfgsize: usize,
/// Size of buffer for BufWriter for [MuninPlugin::fetch](super::MuninPlugin::fetch).
///
/// Defaults to 8192, but if the plugin outputs large datasets, it
/// is useful to increase this.
pub fetchsize: usize,
}
impl Config {
/// Create a new Config with defined plugin_name, also setting
/// [Config::pidfile] to a sensible value using the [Config::plugin_name].
///
/// # Examples
///
/// ```
/// # use munin_plugin::config::Config;
/// let config = Config::new(String::from("great-plugin"));
/// println!("My pidfile is {:?}", config.pidfile);
/// ```
pub fn new(plugin_name: String) -> Self {
trace!("Creating new config for plugin {plugin_name}");
let pd = plugin_name.clone();
let mut cfg = Self {
plugin_name,
..Default::default()
};
cfg.pidfile = cfg.plugin_statedir.join(pd + ".pid");
cfg
}
}
/// Useful defaults, if possible based on munin environment.
impl Default for Config {
/// Set default values, try to read munin environment variables to
/// fill [Config::plugin_statedir] and [Config::dirtyconfig].
/// [Config::plugin_statedir] falls back to _/tmp_ if no munin
/// environment variables are present.
fn default() -> Self {
let statedir =
PathBuf::from(env::var("MUNIN_PLUGSTATE").unwrap_or_else(|_| String::from("/tmp")));
Self {
plugin_name: String::from("Simple munin plugin in Rust"),
plugin_statedir: statedir.clone(),
dirtyconfig: match env::var("MUNIN_CAP_DIRTYCONFIG") {
Ok(val) => val.eq(&"1"),
Err(_) => false,
},
daemonize: false,
pidfile: statedir.join("munin-plugin.pid"),
cfgsize: 8192,
fetchsize: 8192,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn test_modconfig() {
// Whole set of defaults
let config = Config {
..Default::default()
};
assert_eq!(
config.plugin_name,
String::from("Simple munin plugin in Rust")
);
// Use defaults (except for name)
let mut config2 = Config {
plugin_name: String::from("Lala"),
..Default::default()
};
// Is plugin name as given?
assert_eq!(config2.plugin_name, String::from("Lala"));
// Defaults as expected?
assert!(!config2.daemonize);
assert_eq!(config2.fetchsize, 8192);
config2.pidfile = PathBuf::new();
config2.pidfile.push(&config2.plugin_statedir);
config2.pidfile.push(String::from("Lala.pid"));
let config3 = Config::new(String::from("Lala"));
assert_eq!(config2, config3);
}
}