diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2018-03-01 14:40:31 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2018-03-02 20:47:08 +0100 |
| commit | 6bd3431558524d7c56d1722e943a7f2ceb3afae2 (patch) | |
| tree | e203b6d99bc9d68fbb36a28c7ec651869388bc14 | |
| parent | b662c9ab34fc087e77f2c6cb40d66053f328f04e (diff) | |
| download | mullvadvpn-6bd3431558524d7c56d1722e943a7f2ceb3afae2.tar.xz mullvadvpn-6bd3431558524d7c56d1722e943a7f2ceb3afae2.zip | |
Add coloring to stdout logging
| -rw-r--r-- | mullvad-daemon/Cargo.toml | 4 | ||||
| -rw-r--r-- | mullvad-daemon/src/cli.rs | 8 | ||||
| -rw-r--r-- | mullvad-daemon/src/logging.rs | 91 |
3 files changed, 69 insertions, 34 deletions
diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml index 48bd3c59af..6bba73bbd3 100644 --- a/mullvad-daemon/Cargo.toml +++ b/mullvad-daemon/Cargo.toml @@ -11,11 +11,11 @@ app_dirs = "1.1" chrono = { version = "0.4", features = ["serde"] } clap = "2.25" error-chain = "0.11" -fern = "0.4" +fern = { version = "0.5", features = ["colored"] } futures = "0.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -log = "0.3" +log = "0.4" jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc", tag = "v7.1.1" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc", tag = "v7.1.1" } jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc", tag = "v7.1.1" } diff --git a/mullvad-daemon/src/cli.rs b/mullvad-daemon/src/cli.rs index 0550613232..4c0779bf97 100644 --- a/mullvad-daemon/src/cli.rs +++ b/mullvad-daemon/src/cli.rs @@ -4,7 +4,7 @@ use log; use std::path::PathBuf; pub struct Config { - pub log_level: log::LogLevelFilter, + pub log_level: log::LevelFilter, pub log_file: Option<PathBuf>, pub tunnel_log_file: Option<PathBuf>, pub resource_dir: Option<PathBuf>, @@ -16,9 +16,9 @@ pub fn get_config() -> Config { let matches = app.get_matches(); let log_level = match matches.occurrences_of("v") { - 0 => log::LogLevelFilter::Info, - 1 => log::LogLevelFilter::Debug, - _ => log::LogLevelFilter::Trace, + 0 => log::LevelFilter::Info, + 1 => log::LevelFilter::Debug, + _ => log::LevelFilter::Trace, }; let log_file = matches.value_of_os("log_file").map(PathBuf::from); let tunnel_log_file = matches.value_of_os("tunnel_log_file").map(PathBuf::from); diff --git a/mullvad-daemon/src/logging.rs b/mullvad-daemon/src/logging.rs index 5e20f51bc0..a43b00524a 100644 --- a/mullvad-daemon/src/logging.rs +++ b/mullvad-daemon/src/logging.rs @@ -1,8 +1,10 @@ extern crate fern; +use self::fern::colors::{Color, ColoredLevelConfig}; use chrono; use log; +use std::fmt; use std::io; use std::path::PathBuf; @@ -18,40 +20,73 @@ error_chain! { } } +const SILENCED_CRATES: &[&str] = &[ + "jsonrpc_core", + // jsonrpc_core does some logging under the "rpc" target as well. + "rpc", + "tokio_core", + "tokio_proto", + "jsonrpc_ws_server", + "ws", + "mio", + "hyper", +]; + +const COLORS: ColoredLevelConfig = ColoredLevelConfig { + error: Color::Red, + warn: Color::Yellow, + info: Color::Green, + debug: Color::Blue, + trace: Color::Black, +}; + pub const DATE_TIME_FORMAT_STR: &str = "%Y-%m-%d %H:%M:%S%.3f"; -pub fn init_logger(log_level: log::LogLevelFilter, log_file: Option<&PathBuf>) -> Result<()> { - let silenced_crates = [ - "jsonrpc_core", - // jsonrpc_core does some logging under the "rpc" target as well. - "rpc", - "tokio_core", - "tokio_proto", - "jsonrpc_ws_server", - "ws", - "mio", - "hyper", - ]; - let mut config = fern::Dispatch::new() - .format(|out, message, record| { - out.finish(format_args!( - "[{}][{}][{}] {}", - chrono::Local::now().format(DATE_TIME_FORMAT_STR), - record.target(), - record.level(), - message - )) - }) - .level(log_level) - .chain(io::stdout()); - for silenced_crate in &silenced_crates { - config = config.level_for(*silenced_crate, log::LogLevelFilter::Warn); +pub fn init_logger(log_level: log::LevelFilter, log_file: Option<&PathBuf>) -> Result<()> { + let mut top_dispatcher = fern::Dispatch::new().level(log_level); + for silenced_crate in SILENCED_CRATES { + top_dispatcher = top_dispatcher.level_for(*silenced_crate, log::LevelFilter::Warn); } + + let stdout_dispatcher = fern::Dispatch::new() + .format(move |out, message, record| format_log_message(out, message, record, true)) + .chain(io::stdout()); + top_dispatcher = top_dispatcher.chain(stdout_dispatcher); + if let Some(ref log_file) = log_file { let f = fern::log_file(log_file) .chain_err(|| ErrorKind::WriteFileError(log_file.to_path_buf()))?; - config = config.chain(f); + let file_dispatcher = fern::Dispatch::new() + .format(|out, message, record| format_log_message(out, message, record, false)) + .chain(f); + top_dispatcher = top_dispatcher.chain(file_dispatcher); } - config.apply()?; + top_dispatcher.apply()?; Ok(()) } + +fn format_log_message( + out: fern::FormatCallback, + message: &fmt::Arguments, + record: &log::Record, + color_output: bool, +) { + let timestamp = chrono::Local::now().format(DATE_TIME_FORMAT_STR); + if color_output && cfg!(not(windows)) { + out.finish(format_args!( + "[{}][{}][{}] {}", + timestamp, + record.target(), + COLORS.color(record.level()), + message, + )) + } else { + out.finish(format_args!( + "[{}][{}][{}] {}", + timestamp, + record.target(), + record.level(), + message + )) + } +} |
