resolve #92: add CLI argument to specify log level filter

This commit is contained in:
Ilka Schulz
2024-02-29 13:38:54 +01:00
committed by Karolin Varner
parent 4dab97d84e
commit 262e32fe35
2 changed files with 73 additions and 12 deletions
+51 -8
View File
@@ -1,5 +1,5 @@
use anyhow::{bail, ensure};
use clap::Parser;
use clap::{Parser, Subcommand};
use rosenpass_cipher_traits::Kem;
use rosenpass_ciphers::kem::StaticKem;
use rosenpass_secret_memory::file::StoreSecret;
@@ -12,9 +12,50 @@ use crate::protocol::{SPk, SSk, SymKey};
use super::config;
/// struct holding all CLI arguments for `clap` crate to parse
#[derive(Parser, Debug)]
#[command(author, version, about, long_about)]
pub enum Cli {
pub struct CliArgs {
/// lowest log level to show log messages at higher levels will be omitted
#[arg(long = "log-level", value_name = "LOG_LEVEL", group = "log-level")]
log_level: Option<log::LevelFilter>,
/// show verbose log output sets log level to "debug"
#[arg(short, long, group = "log-level")]
verbose: bool,
/// show no log output sets log level to "error"
#[arg(short, long, group = "log-level")]
quiet: bool,
#[command(subcommand)]
pub command: CliCommand,
}
impl CliArgs {
/// returns the log level filter set by CLI args
/// returns `None` if the user did not specify any log level filter via CLI
///
/// NOTE: the clap feature of ["argument groups"](https://docs.rs/clap/latest/clap/_derive/_tutorial/chapter_3/index.html#argument-relations)
/// ensures that the user can not specify more than one of the possible log level arguments.
/// Note the `#[arg("group")]` in the [`CliArgs`] struct.
pub fn get_log_level(&self) -> Option<log::LevelFilter> {
if self.verbose {
return Some(log::LevelFilter::Info);
}
if self.quiet {
return Some(log::LevelFilter::Error);
}
if let Some(level_filter) = self.log_level {
return Some(level_filter);
}
None
}
}
/// represents a command specified via CLI
#[derive(Subcommand, Debug)]
pub enum CliCommand {
/// Start Rosenpass in server mode and carry on with the key exchange
///
/// This will parse the configuration file and perform the key exchange
@@ -104,12 +145,14 @@ pub enum Cli {
Man,
}
impl Cli {
pub fn run() -> anyhow::Result<()> {
let cli = Self::parse();
use Cli::*;
match cli {
impl CliCommand {
/// runs the command specified via CLI
///
/// ## TODO
/// - This method consumes the [`CliCommand`] value. It might be wise to use a reference...
pub fn run(self) -> anyhow::Result<()> {
use CliCommand::*;
match self {
Man => {
let man_cmd = std::process::Command::new("man")
.args(["1", "rosenpass"])
+22 -4
View File
@@ -1,13 +1,31 @@
use clap::Parser;
use log::error;
use rosenpass::cli::Cli;
use rosenpass::cli::CliArgs;
use std::process::exit;
/// Catches errors, prints them through the logger, then exits
pub fn main() {
// default to displaying warning and error log messages only
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
// parse CLI arguments
let args = CliArgs::parse();
match Cli::run() {
// init logging
{
let mut log_builder = env_logger::Builder::from_default_env(); // sets log level filter from environment (or defaults)
if let Some(level) = args.get_log_level() {
log_builder.filter_level(level); // set log level filter from CLI args if available
}
log_builder.init();
// // check the effectiveness of the log level filter with the following lines:
// use log::{debug, error, info, trace, warn};
// trace!("trace dummy");
// debug!("debug dummy");
// info!("info dummy");
// warn!("warn dummy");
// error!("error dummy");
}
match args.command.run() {
Ok(_) => {}
Err(e) => {
error!("{e}");