use crate::{
cli::actions::Action,
collectors::{
COLLECTOR_NAMES, Collector, all_factories,
util::{get_excluded_databases, set_excluded_databases},
},
};
use anyhow::{Result, anyhow};
use clap::ArgMatches;
use secrecy::SecretString;
use tracing::info;
pub fn handler(matches: &clap::ArgMatches) -> Result<Action> {
init_excluded_databases(matches);
info!("Excluded databases: {:?}", get_excluded_databases());
let port = matches
.get_one::<u16>("port")
.copied()
.ok_or_else(|| anyhow!("Port is required. Please provide it using the --port flag."))?;
let dsn = SecretString::from(
matches
.get_one::<String>("dsn")
.map(|s: &String| s.to_string())
.ok_or_else(|| anyhow!("DSN is required. Please provide it using the --dsn flag."))?,
);
Ok(Action::Run {
port,
dsn,
collectors: get_enabled_collectors(matches),
})
}
fn init_excluded_databases(matches: &ArgMatches) {
let excludes: Vec<String> = matches
.get_many::<String>("exclude-databases")
.map(|vals| {
vals.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect()
})
.unwrap_or_default();
set_excluded_databases(excludes);
}
pub fn get_enabled_collectors(matches: &ArgMatches) -> Vec<String> {
let factories = all_factories();
COLLECTOR_NAMES
.iter()
.filter(|&name| {
let enable_flag = format!("collector.{}", name);
let disable_flag = format!("no-collector.{}", name);
if matches.get_flag(&disable_flag) {
return false;
}
if matches.get_flag(&enable_flag) {
return true;
}
if let Some(factory) = factories.get(name) {
let collector = factory();
collector.enabled_by_default()
} else {
false }
})
.map(|&name| name.to_string())
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cli::commands;
#[test]
fn test_get_enabled_collectors_defaults() {
let command = commands::new();
let matches = command.get_matches_from(vec!["pg_exporter"]);
let enabled = get_enabled_collectors(&matches);
assert!(enabled.contains(&"default".to_string()));
assert!(enabled.contains(&"activity".to_string()));
assert!(enabled.contains(&"vacuum".to_string()));
}
#[test]
fn test_get_enabled_collectors_explicit_enable() {
let command = commands::new();
let matches =
command.get_matches_from(vec!["pg_exporter", "--collector.locks", "--collector.stat"]);
let enabled = get_enabled_collectors(&matches);
assert!(enabled.contains(&"locks".to_string()));
assert!(enabled.contains(&"stat".to_string()));
assert!(enabled.contains(&"default".to_string()));
}
#[test]
fn test_get_enabled_collectors_explicit_disable() {
let command = commands::new();
let matches = command.get_matches_from(vec!["pg_exporter", "--no-collector.vacuum"]);
let enabled = get_enabled_collectors(&matches);
assert!(!enabled.contains(&"vacuum".to_string()));
assert!(enabled.contains(&"default".to_string()));
assert!(enabled.contains(&"activity".to_string()));
}
#[test]
fn test_get_enabled_collectors_disable_all_defaults() {
let command = commands::new();
let matches = command.get_matches_from(vec![
"pg_exporter",
"--no-collector.default",
"--no-collector.activity",
"--no-collector.vacuum",
]);
let enabled = get_enabled_collectors(&matches);
assert!(!enabled.contains(&"default".to_string()));
assert!(!enabled.contains(&"activity".to_string()));
assert!(!enabled.contains(&"vacuum".to_string()));
}
}