summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-03-01 14:40:31 +0100
committerLinus Färnstrand <linus@mullvad.net>2018-03-02 20:47:08 +0100
commit6bd3431558524d7c56d1722e943a7f2ceb3afae2 (patch)
treee203b6d99bc9d68fbb36a28c7ec651869388bc14
parentb662c9ab34fc087e77f2c6cb40d66053f328f04e (diff)
downloadmullvadvpn-6bd3431558524d7c56d1722e943a7f2ceb3afae2.tar.xz
mullvadvpn-6bd3431558524d7c56d1722e943a7f2ceb3afae2.zip
Add coloring to stdout logging
-rw-r--r--mullvad-daemon/Cargo.toml4
-rw-r--r--mullvad-daemon/src/cli.rs8
-rw-r--r--mullvad-daemon/src/logging.rs91
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
+ ))
+ }
+}