Skip to content

Commit

Permalink
Initial attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
pvshvp-oss committed Apr 12, 2024
1 parent ddcc2f2 commit 5b37333
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 93 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ paxy = { path = "paxy" }
# Logging
tracing = "0.1"
tracing-appender = "0.2"
tracing-subscriber = "0.3"
tracing-subscriber = { version = "0.3", features = ["serde", "tracing-serde"] }

# Configuration
figment = "0.10"
Expand Down
34 changes: 16 additions & 18 deletions paxy/src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
/// local paths. overridden by environment variables starting with `PAXY_`,
/// overridden by the configuration file specified by the commandline.
/// Values from only files with supported file extensions would be merged.
pub fn init_config<C>(cli_modifier: C) -> Result<(Config, Vec<PathBuf>), Error>
pub fn init_config<C>(cli_modifier: &C) -> Result<(Config, Vec<PathBuf>), Error>
where
C: clap::Parser + ui::CliModifier + fmt::Debug,
<C as ui::GlobalArguments>::L: LogLevel,
C: ui::CliModifier,
<C as ui::GlobalArguments>::L: clap_verbosity_flag::LogLevel,
{
let mut candidate_config_filepath_stubs: Vec<PathBuf> = Vec::new();

Expand Down Expand Up @@ -35,17 +35,14 @@ where
// Merge configuration values from global and local filepaths
figment = candidate_config_filepath_stubs
.iter()
.fold(
figment,
move |figment, candidate_config_filepath_stub| {
admerge_from_stub(candidate_config_filepath_stub, figment)
},
);
.fold(figment, move |figment, candidate_config_filepath_stub| {
admerge_from_stub(candidate_config_filepath_stub, figment)
});

// Merge configuration values from environment variables
figment = figment.admerge(Env::prefixed(&format!("{}_", *app::APP_NAME)));

// Merge configuration values from additional config filepaths (usually
// Merge configuration values from additional config filepaths (usually
// specified through CLI)
if let Some(additional_config_filepath) = cli_modifier.config_file() {
if let Some(parent) = additional_config_filepath.parent() {
Expand All @@ -62,17 +59,17 @@ where
// These are not set to be optional, so only action-required states are
// merged with the configuration
if cli_modifier.is_uncolored() {
figment.admerge(("no_color", true));
figment = figment.admerge(("no_color", true));
}
if let Some(log_level_filter) = cli_input.verbosity_filter() {
figment.admerge(("log_level_filter", log_level_filter));
if let Some(log_level_filter) = cli_modifier.verbosity_filter() {
figment = figment.admerge(("log_level_filter", log_level_filter));
}

Ok((
figment
.extract()
.context(ExtractConfigSnafu {})?,
candidate_config_filepath_stubs
candidate_config_filepath_stubs,
))
}

Expand All @@ -96,7 +93,7 @@ fn admerge_from_stub(candidate_config_filepath_stub: &PathBuf, mut figment: Figm
pub struct Config {
pub log_directory: Option<String>,

pub log_level_filter: Option<log::LevelFilter>,
pub log_level_filter: Option<LevelFilter>,

pub no_color: Option<bool>,
}
Expand All @@ -111,7 +108,7 @@ impl Default for Config {
fn default() -> Self {
Config {
log_directory: None,
log_level_filter: Some(log::LevelFilter::Info),
log_level_filter: Some(LevelFilter::Info),
no_color: Some(false),
}
}
Expand Down Expand Up @@ -151,7 +148,7 @@ pub enum Error {

// region: IMPORTS

use std::path::{Path, PathBuf};
use std::path::PathBuf;

use figment::{
providers::{Env, Format, Json, Toml, Yaml},
Expand All @@ -163,7 +160,8 @@ use figment::{
};
use serde::{Deserialize, Serialize};
use snafu::{OptionExt, ResultExt, Snafu};
use log::LevelFilter;

use crate::{ui, app};
use crate::{app, ui};

// endregion: IMPORTS
17 changes: 15 additions & 2 deletions paxy/src/app/logging.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
pub fn init_log(
preferred_log_dirpath: Option<PathBuf>,
preferred_log_level_filter: Option<LevelFilter>,
preferred_log_level_filter: Option<log::LevelFilter>,
) -> Result<(Handle, PathBuf), Error> {
let log_filename = format!("{}.log", *app::APP_NAME);
let log_dirpath = obtain_log_dirpath(preferred_log_dirpath)?;
let log_file_appender =
tracing_appender::rolling::daily(log_dirpath.clone(), log_filename.clone());
let log_level_filter = preferred_log_level_filter.unwrap_or(LevelFilter::INFO);
let log_level_filter = tracing_level_filter_from_log_level_filter(
preferred_log_level_filter.unwrap_or(log::LevelFilter::Info),
);

// Obtain writers to various logging destinations and worker guards (for
// keeping the streams alive)
Expand Down Expand Up @@ -188,6 +190,17 @@ fn obtain_log_dirpath(preferred_log_dirpath: Option<PathBuf>) -> Result<PathBuf,
})
}

fn tracing_level_filter_from_log_level_filter(level_filter: log::LevelFilter) -> LevelFilter {
match level_filter {
log::LevelFilter::Off => LevelFilter::OFF,
log::LevelFilter::Error => LevelFilter::ERROR,
log::LevelFilter::Warn => LevelFilter::WARN,
log::LevelFilter::Info => LevelFilter::INFO,
log::LevelFilter::Debug => LevelFilter::DEBUG,
log::LevelFilter::Trace => LevelFilter::TRACE,
}
}

type OutputModeSwitchFunction = Box<dyn FnOnce(LoggingMode) -> Result<(), Error>>;

pub struct Handle {
Expand Down
132 changes: 60 additions & 72 deletions paxy/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,17 @@ where
let cli_input = C::parse();

// Obtain user configuration
let (figment, config_filepaths) = config::init_config(
cli_input
.config_file()
.as_ref()
.map(|f| PathBuf::as_path(&f)),
)
.context(app::ConfigSnafu {})
.context(crate::AppSnafu)?;

if cli_input.is_uncolored() {
figment.admerge(("no_color", true));
anstream::ColorChoice::Never.write_global();
owo_colors::set_override(false);
}
if let Some(log_level_filter) = cli_input.verbosity_filter() {
figment.admerge(("log_level_filter", log_level_filter));
}


let (config, config_filepaths) = config::init_config(&cli_input)
.context(app::ConfigSnafu {})
.context(crate::AppSnafu)?;

// Turn off colors if needed
let mut is_cli_uncolored = cli_input.is_uncolored();
if !is_cli_uncolored {
if let Some(no_color) = config.no_color {
is_cli_uncolored = no_color;
if let Some(no_color) = config.no_color {
if no_color {
anstream::ColorChoice::Never.write_global();
owo_colors::set_override(false);
}
}
if is_cli_uncolored {
anstream::ColorChoice::Never.write_global();
owo_colors::set_override(false);
}

// Begin logging with preferred log directory and preferred verbosity
let config_log_dirpath = config
Expand All @@ -52,10 +32,7 @@ where
.parse()
.ok()
});
let verbosity_filter = cli_input
.verbosity_filter()
.or(config_verbosity_filter);
let (mut handle, log_filepath) = logging::init_log(config_log_dirpath, verbosity_filter)
let (mut handle, log_filepath) = logging::init_log(config_log_dirpath, config_verbosity_filter.into())
.context(app::LoggingSnafu {})
.context(crate::AppSnafu {})?;

Expand All @@ -77,7 +54,15 @@ where
.context(crate::AppSnafu {})?;
}

// Welcome message
emit_welcome_messages();
emit_diagnostic_messages(config_filepaths, log_filepath, &cli_input);
emit_test_messages();

Ok((cli_input, handle.worker_guards))
}

fn emit_welcome_messages() {
// Welcome messages
tracing::debug!(
"{} - {}",
"Paxy".bold(),
Expand All @@ -89,41 +74,13 @@ where
"shivanandvp".italic(),
"<pvshvp.oss@gmail.com, shivanandvp@rebornos.org>".italic()
);
tracing::debug!(
target:"TEST", "{}{}{}{}{}{}{}{}",
"███".black(),
"███".red(),
"███".green(),
"███".yellow(),
"███".blue(),
"███".purple(),
"███".cyan(),
"███".white()
);
tracing::debug!(
target:"TEST", "{}{}{}{}{}{}{}{}",
"███".bright_black(),
"███".bright_red(),
"███".bright_green(),
"███".bright_yellow(),
"███".bright_blue(),
"███".bright_purple(),
"███".bright_cyan(),
"███".bright_white()
);

if cli_input.is_test() {
// Test messages
tracing::trace!(target:"TEST", "{} Testing trace!...", console::Emoji("🧪", ""));
tracing::debug!(target:"TEST", "{} Testing debug!...", console::Emoji("🧪", ""));
tracing::info!(target:"TEST", "{} Testing info!...", console::Emoji("🧪", ""));
tracing::warn!(target:"TEST", "{} Testing warn!...", console::Emoji("🧪", ""));
tracing::error!(target:"TEST", "{} Testing error!...", console::Emoji("🧪", ""));

tracing::info!(target:"JSON", "{} Testing: {}", console::Emoji("🧪", ""), "{\"JSON\": \"Target\"}");
tracing::info!(target:"PLAIN", "{} Testing: Plain Target", console::Emoji("🧪", ""));
}
}

fn emit_diagnostic_messages<C>(config_filepaths: Vec<PathBuf>, log_filepath: PathBuf, cli_input: &C)
where
C: clap::Parser + CliModifier + fmt::Debug,
<C as GlobalArguments>::L: LogLevel,
{
tracing::debug!(
"{} The {} is {}... {}",
console::Emoji("⚙️", ""),
Expand Down Expand Up @@ -160,8 +117,40 @@ where
.dimmed(),
cli_input.dimmed()
);
}

Ok((cli_input, handle.worker_guards))
fn emit_test_messages() {
tracing::debug!(
target:"TEST", "{}{}{}{}{}{}{}{}",
"███".black(),
"███".red(),
"███".green(),
"███".yellow(),
"███".blue(),
"███".purple(),
"███".cyan(),
"███".white()
);
tracing::debug!(
target:"TEST", "{}{}{}{}{}{}{}{}",
"███".bright_black(),
"███".bright_red(),
"███".bright_green(),
"███".bright_yellow(),
"███".bright_blue(),
"███".bright_purple(),
"███".bright_cyan(),
"███".bright_white()
);

tracing::trace!(target:"TEST", "{} Testing trace!...", console::Emoji("🧪", ""));
tracing::debug!(target:"TEST", "{} Testing debug!...", console::Emoji("🧪", ""));
tracing::info!(target:"TEST", "{} Testing info!...", console::Emoji("🧪", ""));
tracing::warn!(target:"TEST", "{} Testing warn!...", console::Emoji("🧪", ""));
tracing::error!(target:"TEST", "{} Testing error!...", console::Emoji("🧪", ""));

tracing::info!(target:"JSON", "{} Testing: {}", console::Emoji("🧪", ""), "{\"JSON\": \"Target\"}");
tracing::info!(target:"PLAIN", "{} Testing: Plain Target", console::Emoji("🧪", ""));
}

impl<T> CliModifier for T
Expand All @@ -177,15 +166,15 @@ where
{
fn verbosity_filter(&self) -> Option<LevelFilter> {
if self.is_plain() || self.is_json() {
return Some(LevelFilter::INFO);
return Some(LevelFilter::Info);
}

let verbosity_flag_filter = self
.verbosity()
.log_level_filter();

if verbosity_flag_filter < clap_verbosity_flag::LevelFilter::Debug && self.is_debug() {
return Some(LevelFilter::DEBUG);
return Some(LevelFilter::Debug);
}

verbosity_flag_filter
Expand Down Expand Up @@ -215,7 +204,7 @@ pub trait GlobalArguments {

fn config_file(&self) -> &Option<PathBuf>;

fn is_json(&self) -> &Option<bool>;
fn is_json(&self) -> bool;

fn is_plain(&self) -> bool;

Expand Down Expand Up @@ -247,8 +236,7 @@ use clap_verbosity_flag::LogLevel;
use owo_colors::OwoColorize;
use snafu::{ResultExt, Snafu};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::filter::LevelFilter;
use figment;
use log::LevelFilter;

use crate::app::{self, config, logging};

Expand Down

0 comments on commit 5b37333

Please sign in to comment.