You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.7 KiB
126 lines
3.7 KiB
6 years ago
|
use std::fs::File;
|
||
|
use std::io::Read;
|
||
|
use failure::Fallible;
|
||
|
use serde::Deserialize;
|
||
|
use serde::Serialize;
|
||
|
|
||
|
const CONFIG_FILE: &str = "manabu.toml";
|
||
|
|
||
|
const SOFTWARE_NAME: &str = env!("CARGO_PKG_NAME");
|
||
|
|
||
|
/// 3rd-party libraries that produce log spam - we set these to a fixed higher level
|
||
|
/// to allow using e.g. TRACE without drowing our custom messages
|
||
|
const SPAMMY_LIBS: [&str; 5] = ["tokio_reactor", "hyper", "reqwest", "mio", "want"];
|
||
|
|
||
|
#[derive(SmartDefault,Serialize,Deserialize,Debug)]
|
||
|
#[serde(default)]
|
||
|
pub struct Config {
|
||
|
#[default="info"]
|
||
|
logging: String,
|
||
|
pub instance: String,
|
||
|
#[default="manabu_store.json"]
|
||
|
pub store: String,
|
||
|
}
|
||
|
|
||
|
const LOG_LEVELS: [&str; 5] = ["error", "warn", "info", "debug", "trace"];
|
||
|
|
||
|
/// Load the shared config file
|
||
|
fn load_config(file: &str) -> Fallible<Config> {
|
||
|
let mut file = File::open(file)?;
|
||
|
|
||
|
let mut buf = String::new();
|
||
|
file.read_to_string(&mut buf)?;
|
||
|
|
||
|
let config: Config = toml::from_str(&buf)?;
|
||
|
|
||
|
// Validations
|
||
|
if !LOG_LEVELS.contains(&config.logging.as_str()) {
|
||
|
bail!("Invalid value for \"logging\"");
|
||
|
}
|
||
|
|
||
|
Ok(config)
|
||
|
}
|
||
|
|
||
|
pub(crate) fn init() -> Fallible<Config> {
|
||
|
let version = format!("{}, built from {}", env!("CARGO_PKG_VERSION"), env!("GIT_REV"));
|
||
|
let argv =
|
||
|
clap::App::new(SOFTWARE_NAME)
|
||
|
.version(version.as_str())
|
||
|
.arg(
|
||
|
clap::Arg::with_name("config")
|
||
|
.short("c")
|
||
|
.long("config")
|
||
|
.value_name("FILE")
|
||
|
.help("Sets a custom config file (JSON)")
|
||
|
.takes_value(true),
|
||
|
)
|
||
|
.arg(clap::Arg::with_name("v").short("v").multiple(true).help(
|
||
|
"Sets the level of verbosity (adds to the level configured in the config file)",
|
||
|
))
|
||
|
.arg(
|
||
|
clap::Arg::with_name("log")
|
||
|
.short("l")
|
||
|
.long("log")
|
||
|
.value_name("LEVEL")
|
||
|
.help("Set custom logging level (error,warning,info,debug,trace)")
|
||
|
.takes_value(true),
|
||
|
)
|
||
|
.get_matches();
|
||
|
|
||
|
let confile = argv.value_of("config").unwrap_or(CONFIG_FILE);
|
||
|
|
||
|
println!("{}\nrun with -h for help", SOFTWARE_NAME);
|
||
|
println!("config file: {}", confile);
|
||
|
|
||
|
let mut config = load_config(confile).unwrap_or_else(|e| {
|
||
|
println!("Error loading config file: {}", e);
|
||
|
Default::default()
|
||
|
});
|
||
|
|
||
|
if let Some(l) = argv.value_of("log") {
|
||
|
if !LOG_LEVELS.contains(&config.logging.as_str()) {
|
||
|
bail!("Invalid value for \"logging\"");
|
||
|
}
|
||
|
config.logging = l.to_owned();
|
||
|
}
|
||
|
|
||
|
if argv.is_present("v") {
|
||
|
// bump verbosity if -v's are present
|
||
|
let pos = LOG_LEVELS
|
||
|
.iter()
|
||
|
.position(|x| x == &config.logging)
|
||
|
.unwrap();
|
||
|
|
||
|
config.logging = match LOG_LEVELS
|
||
|
.iter()
|
||
|
.nth(pos + argv.occurrences_of("v") as usize)
|
||
|
{
|
||
|
Some(new_level) => new_level.to_string(),
|
||
|
None => "trace".to_owned(),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
println!("log level: {}", config.logging);
|
||
|
|
||
|
let env = env_logger::Env::default().default_filter_or(&config.logging);
|
||
|
let mut builder = env_logger::Builder::from_env(env);
|
||
|
builder.format_timestamp_millis();
|
||
|
|
||
|
// set logging level for spammy libs. Ensure the configured log level is not exceeded
|
||
|
let mut lib_level = log::LevelFilter::Info;
|
||
|
if config.logging == "warn" {
|
||
|
lib_level = log::LevelFilter::Warn;
|
||
|
}
|
||
|
else if config.logging == "error" {
|
||
|
lib_level = log::LevelFilter::Error;
|
||
|
}
|
||
|
|
||
|
for lib in &SPAMMY_LIBS {
|
||
|
builder.filter_module(lib, lib_level);
|
||
|
}
|
||
|
|
||
|
builder.init();
|
||
|
|
||
|
Ok(config)
|
||
|
}
|