init logger in aquatic_cli_helpers crate

This commit is contained in:
Joakim Frostegård 2020-08-02 21:21:58 +02:00
parent 427c0bc7c3
commit 8d58f8bb70
15 changed files with 113 additions and 119 deletions

3
Cargo.lock generated
View file

@ -43,6 +43,7 @@ dependencies = [
"anyhow",
"gumdrop",
"serde",
"simplelog",
"toml",
]
@ -78,7 +79,6 @@ dependencies = [
"quickcheck_macros",
"rand",
"serde",
"simplelog",
"smartstring",
"socket2",
]
@ -210,7 +210,6 @@ dependencies = [
"quickcheck_macros",
"rand",
"serde",
"simplelog",
"socket2",
"tungstenite",
]

View file

@ -2,9 +2,6 @@
## General
* init logging in cli helper crate? kind of tricky, requires cli helper
knowledge of config, such as config implementing a trait to get log
level
* automatic tests running real clients in container?
## aquatic_http_load_test

View file

@ -9,4 +9,5 @@ license = "Apache-2.0"
anyhow = "1"
gumdrop = "0.8"
serde = { version = "1", features = ["derive"] }
simplelog = "0.8"
toml = "0.5"

View file

@ -3,7 +3,34 @@ use std::io::Read;
use anyhow::Context;
use gumdrop::Options;
use serde::{Serialize, de::DeserializeOwned};
use serde::{Serialize, Deserialize, de::DeserializeOwned};
use simplelog::{ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
Off,
Error,
Warn,
Info,
Debug,
Trace
}
impl Default for LogLevel {
fn default() -> Self {
Self::Error
}
}
pub trait Config: Default + Serialize + DeserializeOwned {
fn get_log_level(&self) -> Option<LogLevel> {
None
}
}
#[derive(Debug, Options)]
@ -21,7 +48,7 @@ pub fn run_app_with_cli_and_config<T>(
title: &str,
// Function that takes config file and runs application
app_fn: fn(T) -> anyhow::Result<()>,
) where T: Default + Serialize + DeserializeOwned {
) where T: Config {
::std::process::exit(match run_inner(title, app_fn) {
Ok(()) => 0,
Err(err) => {
@ -37,7 +64,7 @@ fn run_inner<T>(
title: &str,
// Function that takes config file and runs application
app_fn: fn(T) -> anyhow::Result<()>,
) -> anyhow::Result<()> where T: Default + Serialize + DeserializeOwned {
) -> anyhow::Result<()> where T: Config {
let args: Vec<String> = ::std::env::args().collect();
let opts = AppOptions::parse_args_default(&args[1..])?;
@ -51,15 +78,36 @@ fn run_inner<T>(
Ok(())
} else if let Some(config_file) = opts.config_file {
let config = config_from_toml_file(config_file)?;
let config: T = config_from_toml_file(config_file)?;
if let Some(log_level) = config.get_log_level(){
start_logger(log_level)?;
}
app_fn(config)
} else {
app_fn(T::default())
let config = T::default();
if let Some(log_level) = config.get_log_level(){
start_logger(log_level)?;
}
app_fn(config)
}
}
fn print_help(title: &str, opt_error: Option<anyhow::Error>){
println!("{}", title);
if let Some(error) = opt_error {
println!("\nError: {:#}.", error);
}
println!("\n{}", AppOptions::usage());
}
fn config_from_toml_file<T>(path: String) -> anyhow::Result<T>
where T: DeserializeOwned
{
@ -87,12 +135,27 @@ fn default_config_as_toml<T>() -> String
}
fn print_help(title: &str, opt_error: Option<anyhow::Error>){
println!("{}", title);
fn start_logger(log_level: LogLevel) -> ::anyhow::Result<()> {
let level_filter = match log_level{
LogLevel::Off => LevelFilter::Off,
LogLevel::Error => LevelFilter::Error,
LogLevel::Warn => LevelFilter::Warn,
LogLevel::Info => LevelFilter::Info,
LogLevel::Debug => LevelFilter::Debug,
LogLevel::Trace => LevelFilter::Trace,
};
if let Some(error) = opt_error {
println!("\nError: {:#}.", error);
}
// Note: logger doesn't seem to pick up thread names. Not a huge loss.
let simplelog_config = ConfigBuilder::new()
.set_time_to_local(true)
.set_location_level(LevelFilter::Off)
.build();
println!("\n{}", AppOptions::usage());
}
TermLogger::init(
level_filter,
simplelog_config,
TerminalMode::Stderr
).context("Couldn't initialize logger")?;
Ok(())
}

View file

@ -32,7 +32,6 @@ parking_lot = "0.11"
privdrop = "0.3"
rand = { version = "0.7", features = ["small_rng"] }
serde = { version = "1", features = ["derive"] }
simplelog = "0.8"
smartstring = "0.2"
socket2 = { version = "0.3", features = ["reuseport"] }

View file

@ -1,8 +1,5 @@
use anyhow::Context;
use aquatic_cli_helpers::run_app_with_cli_and_config;
use simplelog::{ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
use aquatic_http::config::{Config, LogLevel};
use aquatic_http::config::Config;
#[global_allocator]
@ -12,33 +9,6 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
fn main(){
run_app_with_cli_and_config::<Config>(
"aquatic: BitTorrent (HTTP/TLS) tracker",
run
aquatic_http::run
)
}
// almost identical to ws version
fn run(config: Config) -> anyhow::Result<()> {
let level_filter = match config.log_level {
LogLevel::Off => LevelFilter::Off,
LogLevel::Error => LevelFilter::Error,
LogLevel::Warn => LevelFilter::Warn,
LogLevel::Info => LevelFilter::Info,
LogLevel::Debug => LevelFilter::Debug,
LogLevel::Trace => LevelFilter::Trace,
};
// Note: logger doesn't seem to pick up thread names. Not a huge loss.
let simplelog_config = ConfigBuilder::new()
.set_time_to_local(true)
.set_location_level(LevelFilter::Off)
.build();
TermLogger::init(
level_filter,
simplelog_config,
TerminalMode::Stderr
).context("Couldn't initialize logger")?;
aquatic_http::run(config)
}

View file

@ -2,24 +2,7 @@ use std::net::SocketAddr;
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
Off,
Error,
Warn,
Info,
Debug,
Trace
}
impl Default for LogLevel {
fn default() -> Self {
Self::Error
}
}
use aquatic_cli_helpers::LogLevel;
#[derive(Clone, Debug, Serialize, Deserialize)]
@ -38,6 +21,13 @@ pub struct Config {
}
impl aquatic_cli_helpers::Config for Config {
fn get_log_level(&self) -> Option<LogLevel>{
Some(self.log_level.clone())
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct TlsConfig {

View file

@ -15,6 +15,9 @@ pub struct Config {
}
impl aquatic_cli_helpers::Config for Config {}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct NetworkConfig {

View file

@ -22,6 +22,9 @@ pub struct Config {
}
impl aquatic_cli_helpers::Config for Config {}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct NetworkConfig {

View file

@ -23,4 +23,7 @@ impl Default for BenchConfig {
num_hashes_per_scrape_request: 20,
}
}
}
}
impl aquatic_cli_helpers::Config for BenchConfig {}

View file

@ -32,6 +32,9 @@ pub fn main(){
}
impl aquatic_cli_helpers::Config for Config {}
fn run(config: Config) -> ::anyhow::Result<()> {
if config.handler.weight_announce + config.handler.weight_connect + config.handler.weight_scrape == 0 {
panic!("Error: at least one weight must be larger than zero.");

View file

@ -31,7 +31,6 @@ privdrop = "0.3"
rand = { version = "0.7", features = ["small_rng"] }
serde = { version = "1", features = ["derive"] }
socket2 = { version = "0.3", features = ["reuseport"] }
simplelog = "0.8"
tungstenite = "0.11"
[dev-dependencies]

View file

@ -1,8 +1,5 @@
use anyhow::Context;
use aquatic_cli_helpers::run_app_with_cli_and_config;
use simplelog::{ConfigBuilder, LevelFilter, TermLogger, TerminalMode};
use aquatic_ws::config::{Config, LogLevel};
use aquatic_ws::config::Config;
#[global_allocator]
@ -12,32 +9,6 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
fn main(){
run_app_with_cli_and_config::<Config>(
"aquatic: webtorrent tracker",
run
aquatic_ws::run
)
}
fn run(config: Config) -> anyhow::Result<()> {
let level_filter = match config.log_level {
LogLevel::Off => LevelFilter::Off,
LogLevel::Error => LevelFilter::Error,
LogLevel::Warn => LevelFilter::Warn,
LogLevel::Info => LevelFilter::Info,
LogLevel::Debug => LevelFilter::Debug,
LogLevel::Trace => LevelFilter::Trace,
};
// Note: logger doesn't seem to pick up thread names. Not a huge loss.
let simplelog_config = ConfigBuilder::new()
.set_time_to_local(true)
.set_location_level(LevelFilter::Off)
.build();
TermLogger::init(
level_filter,
simplelog_config,
TerminalMode::Stderr
).context("Couldn't initialize logger")?;
aquatic_ws::run(config)
}

View file

@ -2,24 +2,7 @@ use std::net::SocketAddr;
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LogLevel {
Off,
Error,
Warn,
Info,
Debug,
Trace
}
impl Default for LogLevel {
fn default() -> Self {
Self::Error
}
}
use aquatic_cli_helpers::LogLevel;
#[derive(Clone, Debug, Serialize, Deserialize)]
@ -38,6 +21,13 @@ pub struct Config {
}
impl aquatic_cli_helpers::Config for Config {
fn get_log_level(&self) -> Option<LogLevel> {
Some(self.log_level.clone())
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct NetworkConfig {

View file

@ -15,6 +15,9 @@ pub struct Config {
}
impl aquatic_cli_helpers::Config for Config {}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct NetworkConfig {