Skip to content

Commit

Permalink
[WIP] Add --log-output argument in commands
Browse files Browse the repository at this point in the history
  • Loading branch information
dlachaume committed Dec 18, 2023
1 parent 6474677 commit a3e6629
Showing 1 changed file with 56 additions and 16 deletions.
72 changes: 56 additions & 16 deletions mithril-client-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,42 @@

mod commands;

use std::path::PathBuf;
use std::sync::Arc;

use anyhow::Context;
use clap::{Parser, Subcommand};
use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind};
use slog::{Drain, Level, Logger};
use slog::{Drain, Fuse, Level, Logger};
use slog_async::Async;
use slog_scope::debug;
use slog_term::Decorator;
use std::io::Write;
use std::sync::Arc;
use std::{fs::File, path::PathBuf};

use mithril_client_cli::common::StdResult;

use commands::{
mithril_stake_distribution::MithrilStakeDistributionCommands, snapshot::SnapshotCommands,
};

enum LogOutputType {
Stdout,
File(String),
}

impl LogOutputType {
fn get_writer(&self) -> StdResult<Box<dyn Write + Send>> {
let writer: Box<dyn Write + Send> = match self {
LogOutputType::Stdout => Box::new(std::io::stdout()),
LogOutputType::File(filepath) => Box::new(
File::create(filepath)
.with_context(|| format!("Can not create output log file: {}", filepath))?,
),
};

Ok(writer)
}
}

#[derive(Parser, Debug, Clone)]
#[clap(name = "mithril-client")]
#[clap(
Expand Down Expand Up @@ -47,6 +69,10 @@ pub struct Args {
/// Enable JSON output for logs displayed according to verbosity level
#[clap(long)]
log_format_json: bool,

/// Redirect the logs to a file
#[clap(long, alias("o"))]
log_output: Option<String>,
}

impl Args {
Expand All @@ -72,24 +98,38 @@ impl Args {
}
}

fn build_logger(&self) -> Logger {
fn get_log_output_type(&self) -> LogOutputType {
if let Some(output_filepath) = &self.log_output {
LogOutputType::File(output_filepath.to_string())
} else {
LogOutputType::Stdout
}
}

fn wrap_drain<D: Decorator + Send + 'static>(&self, decorator: D) -> Fuse<Async> {
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
let drain = slog::LevelFilter::new(drain, self.log_level()).fuse();

slog_async::Async::new(drain).build().fuse()
}

fn build_logger(&self) -> StdResult<Logger> {
let log_output_type = self.get_log_output_type();
let writer = log_output_type.get_writer()?;

let drain = if self.log_format_json {
let drain = slog_bunyan::new(std::io::stdout())
.set_pretty(false)
.build()
.fuse();
let drain = slog_bunyan::new(writer).set_pretty(false).build().fuse();
let drain = slog::LevelFilter::new(drain, self.log_level()).fuse();

slog_async::Async::new(drain).build().fuse()
} else {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::CompactFormat::new(decorator).build().fuse();
let drain = slog::LevelFilter::new(drain, self.log_level()).fuse();

slog_async::Async::new(drain).build().fuse()
match log_output_type {
LogOutputType::Stdout => self.wrap_drain(slog_term::TermDecorator::new().build()),
LogOutputType::File(_) => self.wrap_drain(slog_term::PlainDecorator::new(writer)),
}
};

Logger::root(Arc::new(drain), slog::o!())
Ok(Logger::root(Arc::new(drain), slog::o!()))
}
}

Expand Down Expand Up @@ -135,7 +175,7 @@ impl ArtifactCommands {
async fn main() -> StdResult<()> {
// Load args
let args = Args::parse();
let _guard = slog_scope::set_global_logger(args.build_logger());
let _guard = slog_scope::set_global_logger(args.build_logger()?);

#[cfg(feature = "bundle_openssl")]
openssl_probe::init_ssl_cert_env_vars();
Expand Down

0 comments on commit a3e6629

Please sign in to comment.