slog-rs logging (#171)
* added global slog instance, changed all logging macro formats to include logger instance * adding configuration to logging, allowing for multiple log outputs * updates to test, changes to build docs * rustfmt * moving logging functions into util crate
This commit is contained in:
committed by
Ignotus Peverell
parent
b85006ebe5
commit
8e382a7593
+33
-6
@@ -12,9 +12,35 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/// Various low-level utilities that factor Rust patterns that are frequent
|
||||
/// within the grin codebase.
|
||||
//! Logging, as well as various low-level utilities that factor Rust
|
||||
//! patterns that are frequent within the grin codebase.
|
||||
|
||||
#![deny(non_upper_case_globals)]
|
||||
#![deny(non_camel_case_types)]
|
||||
#![deny(non_snake_case)]
|
||||
#![deny(unused_mut)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate slog;
|
||||
extern crate slog_term;
|
||||
extern crate slog_async;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
// Logging related
|
||||
pub mod logger;
|
||||
pub use logger::{LOGGER, init_logger};
|
||||
|
||||
pub mod types;
|
||||
pub use types::LoggingConfig;
|
||||
|
||||
// other utils
|
||||
use std::cell::{RefCell, Ref};
|
||||
#[allow(unused_imports)]
|
||||
use std::ops::Deref;
|
||||
@@ -22,12 +48,13 @@ use std::ops::Deref;
|
||||
mod hex;
|
||||
pub use hex::*;
|
||||
|
||||
// Encapsulation of a RefCell<Option<T>> for one-time initialization after
|
||||
// construction. This implementation will purposefully fail hard if not used
|
||||
// properly, for example if it's not initialized before being first used
|
||||
// (borrowed).
|
||||
/// Encapsulation of a RefCell<Option<T>> for one-time initialization after
|
||||
/// construction. This implementation will purposefully fail hard if not used
|
||||
/// properly, for example if it's not initialized before being first used
|
||||
/// (borrowed).
|
||||
#[derive(Clone)]
|
||||
pub struct OneTime<T> {
|
||||
/// inner
|
||||
inner: RefCell<Option<T>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2017 The Grin Developers
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Logging wrapper to be used throughout all crates in the workspace
|
||||
use std::fs::OpenOptions;
|
||||
use std::sync::Mutex;
|
||||
use slog::{Logger, Drain, Level, LevelFilter, Duplicate, Discard};
|
||||
use slog_term;
|
||||
use slog_async;
|
||||
|
||||
use types::{LogLevel, LoggingConfig};
|
||||
|
||||
fn convert_log_level(in_level:&LogLevel)->Level{
|
||||
match *in_level {
|
||||
LogLevel::Info => Level::Info,
|
||||
LogLevel::Critical => Level::Critical,
|
||||
LogLevel::Warning => Level::Warning,
|
||||
LogLevel::Debug => Level::Debug,
|
||||
LogLevel::Trace => Level::Trace,
|
||||
LogLevel::Error => Level::Error,
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// Static Logging configuration, should only be set once, before first logging call
|
||||
static ref LOGGING_CONFIG: Mutex<LoggingConfig> = Mutex::new(LoggingConfig::default());
|
||||
/// And a static reference to the logger itself, accessible from all crates
|
||||
pub static ref LOGGER: Logger = {
|
||||
let config = LOGGING_CONFIG.lock().unwrap();
|
||||
let slog_level_stdout = convert_log_level(&config.stdout_log_level);
|
||||
let slog_level_file = convert_log_level(&config.file_log_level);
|
||||
|
||||
//Terminal output drain
|
||||
let terminal_decorator = slog_term::TermDecorator::new().build();
|
||||
let terminal_drain = slog_term::FullFormat::new(terminal_decorator).build().fuse();
|
||||
let terminal_drain = LevelFilter::new(terminal_drain, slog_level_stdout).fuse();
|
||||
let mut terminal_drain = slog_async::Async::new(terminal_drain).build().fuse();
|
||||
|
||||
if !config.log_to_stdout {
|
||||
terminal_drain = slog_async::Async::new(Discard{}).build().fuse();
|
||||
}
|
||||
|
||||
let mut file_drain_final = slog_async::Async::new(Discard{}).build().fuse();
|
||||
|
||||
if config.log_to_file {
|
||||
//File drain
|
||||
let file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.append(config.log_file_append)
|
||||
.truncate(false)
|
||||
.open(&config.log_file_path)
|
||||
.unwrap();
|
||||
|
||||
let file_decorator = slog_term::PlainDecorator::new(file);
|
||||
let file_drain = slog_term::FullFormat::new(file_decorator).build().fuse();
|
||||
let file_drain = LevelFilter::new(file_drain, slog_level_file).fuse();
|
||||
file_drain_final = slog_async::Async::new(file_drain).build().fuse();
|
||||
}
|
||||
|
||||
//Compose file and terminal drains
|
||||
let composite_drain = Duplicate::new(terminal_drain, file_drain_final).fuse();
|
||||
|
||||
let log = Logger::root(composite_drain, o!());
|
||||
log
|
||||
};
|
||||
}
|
||||
|
||||
/// Initialises the logger with the given configuration
|
||||
|
||||
pub fn init_logger(config:Option<LoggingConfig>){
|
||||
if let Some(c) = config {
|
||||
let mut config_ref=LOGGING_CONFIG.lock().unwrap();
|
||||
*config_ref=c.clone();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2017 The Grin Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Logging configuration types
|
||||
|
||||
/// Log level types, as slog's don't implement serialize
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum LogLevel {
|
||||
/// Critical
|
||||
Critical,
|
||||
/// Error
|
||||
Error,
|
||||
/// Warning
|
||||
Warning,
|
||||
/// Info
|
||||
Info,
|
||||
/// Debug
|
||||
Debug,
|
||||
/// Trace
|
||||
Trace,
|
||||
}
|
||||
|
||||
/// Logging config
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LoggingConfig {
|
||||
/// whether to log to stdout
|
||||
pub log_to_stdout: bool,
|
||||
/// logging level for stdout
|
||||
pub stdout_log_level: LogLevel,
|
||||
/// whether to log to file
|
||||
pub log_to_file: bool,
|
||||
/// log file level
|
||||
pub file_log_level: LogLevel,
|
||||
/// Log file path
|
||||
pub log_file_path: String,
|
||||
/// Whether to append to log or replace
|
||||
pub log_file_append: bool,
|
||||
}
|
||||
|
||||
impl Default for LoggingConfig {
|
||||
fn default() -> LoggingConfig {
|
||||
LoggingConfig {
|
||||
log_to_stdout: true,
|
||||
stdout_log_level: LogLevel::Debug,
|
||||
log_to_file: false,
|
||||
file_log_level: LogLevel::Trace,
|
||||
log_file_path: String::from("grin.log"),
|
||||
log_file_append: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user