/******************************************************************************** * Prometheus exporter for monitoring network connectivity using icmp pings * * * * Copyright (C) 2019-2020 Jan Christian Grünhage * * Copyright (C) 2020 Famedly GmbH * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * ********************************************************************************/ use anyhow::{Context, Result}; use clap::{clap_app, crate_authors, crate_description, crate_name, crate_version}; use log::info; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Serialize, Deserialize, Clone)] pub(crate) struct Config { pub(crate) listener: std::net::SocketAddr, pub(crate) hosts: HashMap, } fn setup_clap() -> clap::ArgMatches<'static> { clap_app!(myapp => (name: crate_name!()) (version: crate_version!()) (author: crate_authors!()) (about: crate_description!()) (@arg config: +required "Set config file") (@arg v: -v --verbose ... "Be verbose (you can add this up to 4 times for more logs). By default, only errors are logged, so no output is a good thing.") ) .get_matches() } fn setup_fern(level: u64) { let level = match level { 0 => log::LevelFilter::Error, 1 => log::LevelFilter::Warn, 2 => log::LevelFilter::Info, 3 => log::LevelFilter::Debug, _ => log::LevelFilter::Trace, }; match fern::Dispatch::new() .format(|out, message, record| { out.finish(format_args!( "[{}][{}] {}", chrono::Local::now().format("%Y-%m-%d %H:%M:%S"), record.level(), message )) }) .level(level) .chain(std::io::stdout()) .apply() { Err(_) => { eprintln!("error setting up logging!"); } _ => info!("logging set up properly"), } } fn read_config(path: &str) -> Result { let config_file_content = std::fs::read_to_string(path).context("Couldn't read config file")?; Ok(toml::from_str(&config_file_content).context("Couldn't parse config file")?) } pub(crate) fn setup_app() -> Result { let clap = setup_clap(); setup_fern(clap.occurrences_of("v")); let config_path = clap .value_of("config") .context("Got no config file. clap should've catched this")?; Ok(read_config(config_path).context("Couldn't read config file!")?) }