mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-18 22:17:54 +08:00
refactor output system (#74)
This commit is contained in:
+8
-5
@@ -6,12 +6,15 @@ pub fn output_args<'a>() -> Vec<Arg<'a, 'a>> {
|
||||
.long("output")
|
||||
.short("o")
|
||||
.help("Defines the output format")
|
||||
.value_name("STRING")
|
||||
.value_name("FMT")
|
||||
.possible_values(&["plain", "json"])
|
||||
.default_value("plain"),
|
||||
Arg::with_name("silent")
|
||||
.long("silent")
|
||||
.short("s")
|
||||
.help("Disables any output"),
|
||||
Arg::with_name("log")
|
||||
.long("log")
|
||||
.short("l")
|
||||
.help("Defines the logs level")
|
||||
.value_name("LEVEL")
|
||||
.possible_values(&["error", "warn", "info", "debug", "trace"])
|
||||
.default_value("info"),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
use std::fmt;
|
||||
|
||||
pub enum OutputFmt {
|
||||
Json,
|
||||
Plain,
|
||||
}
|
||||
|
||||
impl From<&str> for OutputFmt {
|
||||
fn from(s: &str) -> Self {
|
||||
match s {
|
||||
"json" => Self::Json,
|
||||
"plain" | _ => Self::Plain,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OutputFmt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
OutputFmt::Json => "JSON",
|
||||
OutputFmt::Plain => "PLAIN",
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
use error_chain::error_chain;
|
||||
use log::{Level, LevelFilter, Metadata, Record};
|
||||
use std::fmt;
|
||||
|
||||
use super::fmt::OutputFmt;
|
||||
|
||||
error_chain! {}
|
||||
|
||||
// Log level struct
|
||||
|
||||
pub struct LogLevel(pub LevelFilter);
|
||||
|
||||
impl From<&str> for LogLevel {
|
||||
fn from(s: &str) -> Self {
|
||||
match s {
|
||||
"error" => Self(LevelFilter::Error),
|
||||
"warn" => Self(LevelFilter::Warn),
|
||||
"debug" => Self(LevelFilter::Debug),
|
||||
"trace" => Self(LevelFilter::Trace),
|
||||
"info" | _ => Self(LevelFilter::Info),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LogLevel {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
// Plain logger
|
||||
|
||||
struct PlainLogger;
|
||||
|
||||
impl log::Log for PlainLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
metadata.level() <= Level::Trace
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if self.enabled(record.metadata()) {
|
||||
if let Level::Error = record.level() {
|
||||
eprintln!("{}", record.args());
|
||||
} else {
|
||||
println!("{}", record.args());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
// JSON logger
|
||||
|
||||
struct JsonLogger;
|
||||
|
||||
impl log::Log for JsonLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
[Level::Error, Level::Info].contains(&metadata.level())
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if self.enabled(record.metadata()) {
|
||||
if let Level::Error = record.level() {
|
||||
eprintln!("{}", record.args());
|
||||
} else {
|
||||
// Should be safe enough to `.unwrap()` since it's
|
||||
// formatted by Himalaya itself
|
||||
print!("{}", serde_json::to_string(record.args()).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
// Init
|
||||
|
||||
pub fn init(fmt: &OutputFmt, level: &LogLevel) -> Result<()> {
|
||||
log::set_boxed_logger(match fmt {
|
||||
&OutputFmt::Json => Box::new(JsonLogger),
|
||||
&OutputFmt::Plain => Box::new(PlainLogger),
|
||||
})
|
||||
.map(|()| log::set_max_level(level.0))
|
||||
.chain_err(|| "Could not init logger")
|
||||
}
|
||||
Reference in New Issue
Block a user