Skip to content

Commit

Permalink
feat(Logging): Add configurable logging
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Apr 3, 2021
1 parent 66069e1 commit cd4ac32
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 60 deletions.
128 changes: 105 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serve-ws = ["warp", "jsonwebtoken"]

request = []
request-stdio = []
request-docker = ["bollard"]
request-http = ["reqwest", "jsonwebtoken"]
request-ws = ["tokio-tungstenite", "jsonwebtoken"]

Expand Down Expand Up @@ -59,14 +60,15 @@ default = [
"serve-http",
"serve-ws",
"request",
"request-stdio",
"request-docker",
"request-http",
"request-stdio",
"request-ws",
"plugins",
"plugins-docker",
"plugins-binary",
"plugins-package",
"plugins-docker",
"plugins-link",
"plugins-package",
"upgrade",
"config",
"format-json",
Expand All @@ -81,8 +83,8 @@ default = [
anyhow = "1.0.40"
bollard = { version = "0.10.1", optional = true }
chrono = "0.4.19"
defaults = "0.2.0"
dirs-next = "2.0.0"
env_logger = "0.8.3"
exitcode = { version = "1.1.2", optional = true }
futures = "0.3.13"
handlebars = { version = "3.5.4", optional = true }
Expand Down Expand Up @@ -112,6 +114,8 @@ tokio = { version = "1.4.0", features = ["full"] }
tokio-tungstenite = { version = "0.14.0", optional = true }
toml = { version = "0.5.8", optional = true }
tracing = "0.1.25"
tracing-appender = "0.1.2"
tracing-subscriber = "0.2.17"
url = "2.2.1"
validator = { version = "0.13.0", features = ["derive"], optional = true}
warp = { version = "0.3.1", optional = true }
Expand Down
87 changes: 73 additions & 14 deletions rust/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use crate::convert;
use crate::open;
use crate::plugins;
use crate::request;
use crate::serve;
use crate::upgrade;
use crate::validate;
use crate::{config, plugins::read_plugins};
use crate::{config, convert, logging, open, plugins, request, serve, upgrade, validate};
use anyhow::Result;
use regex::Regex;
use structopt::StructOpt;
use strum::{Display, EnumVariantNames};

Expand All @@ -18,6 +12,26 @@ use strum::{Display, EnumVariantNames};
pub struct Args {
#[structopt(subcommand)]
pub command: Command,

/// Emit tracing level (and above) log entries
#[structopt(long, conflicts_with_all = &["debug", "info", "warn", "error"])]
pub trace: bool,

/// Emit debug level (and above) log entries
#[structopt(long, conflicts_with_all = &["trace", "info", "warn", "error"])]
pub debug: bool,

/// Emit info level (and above) log entries
#[structopt(long, conflicts_with_all = &["trace", "debug", "warn", "error"])]
pub info: bool,

/// Emit waning level (and above) log entries
#[structopt(long, conflicts_with_all = &["trace", "debug", "info", "error"])]
pub warn: bool,

/// Emit error level log entries only
#[structopt(long, conflicts_with_all = &["trace", "debug", "info", "warn"])]
pub error: bool,
}

#[derive(Debug, Display, StructOpt, EnumVariantNames)]
Expand All @@ -38,7 +52,34 @@ pub enum Command {

pub async fn cli(args: Vec<String>) -> Result<i32> {
// Parse args into a command
let Args { command } = Args::from_iter(args);
let Args {
command,
trace,
debug,
info,
warn,
error,
} = Args::from_iter(args);

// Determine the log level to use on stderr
let level = if trace {
logging::Level::Trace
} else if debug {
logging::Level::Debug
} else if info {
logging::Level::Info
} else if warn {
logging::Level::Warn
} else if error {
logging::Level::Error
} else {
logging::Level::Info
};

// To ensure all log events get written to file, take guards here, so it does
// not get dropped until the end of this function.
// See https://tracing.rs/tracing_appender/non_blocking/struct.workerguard
let _logging_guards = logging::init(Some(level))?;

// If not explicitly upgrading then run an upgrade check in the background
let upgrade_thread = if let Command::Upgrade(_) = command {
Expand All @@ -48,7 +89,7 @@ pub async fn cli(args: Vec<String>) -> Result<i32> {
};

// Load plugins
read_plugins()?;
plugins::read_plugins()?;

// Run the command
let result = match command {
Expand All @@ -65,17 +106,35 @@ pub async fn cli(args: Vec<String>) -> Result<i32> {
// Join the upgrade thread and log any errors
if let Some(upgrade_thread) = upgrade_thread {
if let Err(_error) = upgrade_thread.join() {
// TODO: Log error
tracing::warn!("Error while attempting to join upgrade thread")
}
}

match result {
Ok(_) => Ok(exitcode::OK),
Err(error) => {
// Write the error to the terminal
// TODO Send this to a logger
eprintln!("{}", error);
tracing::error!("{}", error);
Ok(exitcode::SOFTWARE)
}
}
}

/// Parse a vector of command line arguments into parameters of a method call
pub fn parse_params(params: Vec<String>) -> serde_json::Value {
let re = Regex::new(r"(\w+)(:?=)(.+)").unwrap();
let mut object = serde_json::json!({});
for param in params {
if let Some(captures) = re.captures(param.as_str()) {
let (name, kind, value) = (&captures[1], &captures[2], &captures[3]);
if kind == ":=" {
object[name] = match serde_json::from_str(value) {
Ok(value) => value,
Err(_) => serde_json::Value::String(value.to_string()),
};
} else {
object[name] = serde_json::Value::from(value);
}
}
}
object
}

0 comments on commit cd4ac32

Please sign in to comment.