Skip to content

Commit

Permalink
changed the imp of the logger for enabaling resetting the logger
Browse files Browse the repository at this point in the history
  • Loading branch information
avifenesh committed Jun 27, 2023
1 parent f16dbea commit 54289da
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 63 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
},
"editor.insertSpaces": true,
"editor.tabSize": 4,
"editor.codeActionsOnSave": {
Expand All @@ -15,7 +18,6 @@
"logger_core/Cargo.toml",
"csharp/lib/Cargo.toml",
"submodules/redis-rs/Cargo.toml",
"rust-benchmark/Cargo.toml"
],
"rust-analyzer.runnableEnv": {
"REDISRS_SERVER_TYPE": "tcp"
Expand Down
1 change: 1 addition & 0 deletions babushka-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ integer-encoding = "3.0.4"
thiserror = "1"
rand = "0.8.5"
futures-intrusive = "0.5.0"
tracing-subscriber = "0.3.17"
directories = "5.0"

[dev-dependencies]
Expand Down
84 changes: 84 additions & 0 deletions babushka-core/tests/test_logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#[cfg(test)]
mod tests {

use std::fs::{read_dir, read_to_string};

use logger_core::{init, log_trace};
use rand::{distributions::Alphanumeric, Rng};

const FILE_DIRECTORY: &str = "babushka-logs";

fn generate_random_string(length: usize) -> String {
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(length)
.map(char::from)
.collect()
}

fn get_file_contents(file_name: &str) -> String {
let files = read_dir(FILE_DIRECTORY).unwrap();
let file = files
.into_iter()
.find(|path| {
path.as_ref()
.unwrap()
.path()
.file_name()
.unwrap()
.to_str()
.unwrap()
.starts_with(file_name)
})
.unwrap();
read_to_string(file.unwrap().path()).unwrap()
}
#[test]
fn log_to_console_works_after_multiple_inits_diff_log_level() {
let identifier = generate_random_string(10);
init(Some(logger_core::Level::Debug), None);
init(Some(logger_core::Level::Trace), None);
log_trace(identifier.clone(), "foo");
}
#[test]
fn log_to_console_works_after_multiple_inits() {
let identifier = generate_random_string(10);
init(Some(logger_core::Level::Trace), None);
init(Some(logger_core::Level::Trace), None);
log_trace(identifier.clone(), "foo");
}
#[test]
fn log_to_file_works_after_multiple_inits() {
let identifier = generate_random_string(10);
init(Some(logger_core::Level::Trace), Some(identifier.as_str()));
log_trace(identifier.clone(), "foo");

init(Some(logger_core::Level::Trace), Some(identifier.as_str()));
log_trace(identifier.clone(), "foo");
let contents = get_file_contents(identifier.as_str());
assert!(
contents.contains(identifier.as_str()),
"Contens: {}",
contents
);
assert!(contents.contains("foo"), "Contens: {}", contents);
}

#[test]
fn log_to_console_works_after_file_init() {}

#[test]
fn log_to_file_works_after_console_init() {
let identifier = generate_random_string(10);
init(Some(logger_core::Level::Trace), None);
init(Some(logger_core::Level::Trace), Some(identifier.as_str()));
log_trace(identifier.clone(), "foo");
let contents = get_file_contents(identifier.as_str());
assert!(
contents.contains(identifier.as_str()),
"Contens: {}",
contents
);
assert!(contents.contains("foo"), "Contens: {}", contents);
}
}
2 changes: 1 addition & 1 deletion babushka-core/tests/utilities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,5 +560,5 @@ pub async fn setup_test_basics(use_tls: bool) -> TestBasics {
#[cfg(test)]
#[ctor::ctor]
fn init() {
logger_core::init_console(logger_core::Level::Debug);
logger_core::init(Some(logger_core::Level::Debug), None);
}
3 changes: 2 additions & 1 deletion logger_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ license = "Apache-2.0"
tracing = "0.1"
tracing-appender = "0.2.2"
once_cell = "1.16.0"
tracing-subscriber = "0.3.16"
file-rotate = "0.7.1"
tracing-subscriber = "0.3.17"
167 changes: 107 additions & 60 deletions logger_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,60 @@
use once_cell::sync::OnceCell;
use std::sync::Once;
use std::sync::RwLock;
use tracing::{self, event};
use tracing_appender::{
non_blocking,
non_blocking::WorkerGuard,
rolling::{RollingFileAppender, Rotation},
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{
filter::Filtered,
fmt::{
format::{DefaultFields, Format},
Layer,
},
layer::Layered,
Registry,
};
use tracing_subscriber::{self, filter::LevelFilter};

// Guard is in charge of making sure that the logs been collected when program stop
pub static GUARD: RwLock<Option<WorkerGuard>> = RwLock::new(None);
use tracing_subscriber::{
self,
filter::{self, LevelFilter},
prelude::*,
reload::{self, Handle},
};

// INIT_ONCE is responsible for making sure that we initiating the logger just once, and every other call to the
// init function will just reload the existing logger
static INIT_ONCE: Once = Once::new();

// reloadable handles for resetting the logger
pub static STDOUT_RELOAD: OnceCell<
RwLock<reload::Handle<Filtered<Layer<Registry>, LevelFilter, Registry>, Registry>>,
> = OnceCell::new();

pub static FILE_RELOAD: OnceCell<
RwLock<
Handle<
Filtered<
Layer<
Layered<
reload::Layer<Filtered<Layer<Registry>, LevelFilter, Registry>, Registry>,
Registry,
>,
DefaultFields,
Format,
RollingFileAppender,
>,
LevelFilter,
Layered<
reload::Layer<Filtered<Layer<Registry>, LevelFilter, Registry>, Registry>,
Registry,
>,
>,
Layered<
reload::Layer<Filtered<Layer<Registry>, LevelFilter, Registry>, Registry>,
Registry,
>,
>,
>,
> = OnceCell::new();

#[derive(Debug)]
pub enum Level {
Expand All @@ -19,7 +65,7 @@ pub enum Level {
Trace = 4,
}
impl Level {
fn to_filter(&self) -> LevelFilter {
fn to_filter(&self) -> filter::LevelFilter {
match self {
Level::Trace => LevelFilter::TRACE,
Level::Debug => LevelFilter::DEBUG,
Expand All @@ -30,59 +76,61 @@ impl Level {
}
}

fn tracing_format(
) -> tracing_subscriber::fmt::format::Format<tracing_subscriber::fmt::format::Compact> {
tracing_subscriber::fmt::format()
.with_source_location(false)
.with_target(false)
.compact()
}

// Initialize a logger that writes the received logs to a file under the babushka-logs folder.
// The file name will be prefixed with the current timestamp, and will be replaced every hour.
// This logger doesn't block the calling thread, and will save only logs of the given level or above.
pub fn init_file(minimal_level: Level, file_name: &str) -> Level {
let file_appender = RollingFileAppender::new(Rotation::HOURLY, "babushka-logs", file_name);
let (non_blocking, _guard) = non_blocking(file_appender);
let mut guard = GUARD.write().unwrap();
*guard = Some(_guard);
let level_filter = minimal_level.to_filter();
let _ = tracing::subscriber::set_global_default(
tracing_subscriber::fmt()
.event_format(tracing_format())
.with_max_level(level_filter)
.with_writer(non_blocking)
.finish(),
);
minimal_level
}

// Initialize the global logger so that it will write the received logs to a file under the babushka-logs folder.
// The file name will be prefixed with the current timestamp, and will be replaced every hour.
// The logger doesn't block the calling thread, and will save only logs of the given level or above.
pub fn init_console(minimal_level: Level) -> Level {
let level_filter = minimal_level.to_filter();
let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout());
let mut guard = GUARD.write().unwrap();
*guard = Some(_guard);
let _ = tracing::subscriber::set_global_default(
tracing_subscriber::fmt()
.event_format(tracing_format())
.with_writer(non_blocking)
.with_max_level(level_filter)
.finish(),
);
minimal_level
}

// Initialize the global logger so that it will write the received logs to the console.
// Initialize the global logger to error level on the first call only
// In any of the calls to the function, including the first - resetting the existence loggers to the new setting
// provided by using the global reloadable handle
// The logger will save only logs of the given level or above.
pub fn init(minimal_level: Option<Level>, file_name: Option<&str>) -> Level {
let level = minimal_level.unwrap_or(Level::Warn);
let level_filter = level.to_filter();
INIT_ONCE.call_once(|| {
let stdout_fmt = tracing_subscriber::fmt::layer()
.with_ansi(true)
.with_filter(LevelFilter::ERROR); // Console logging ERROR by default

let (stdout_layer, stdout_reload) = reload::Layer::new(stdout_fmt);

let file_appender = RollingFileAppender::new(
Rotation::HOURLY,
"babushka-logs",
file_name.unwrap_or("output.log"),
);
let file_fmt = tracing_subscriber::fmt::layer()
.with_ansi(true)
.with_writer(file_appender)
.with_filter(LevelFilter::ERROR); // File logging ERROR by default
let (file_layer, file_reload) = reload::Layer::new(file_fmt);
tracing_subscriber::registry()
.with(stdout_layer)
.with(file_layer)
.init();
let _ = STDOUT_RELOAD.set(RwLock::new(stdout_reload));
let _ = FILE_RELOAD.set(RwLock::new(file_reload));
});

match file_name {
None => init_console(level),
Some(file) => init_file(level, file),
}
None => {
let _ = STDOUT_RELOAD
.get()
.expect("error reloading stdout")
.write()
.expect("error reloading stdout")
.modify(|layer| (*layer.filter_mut() = level_filter));
}
Some(file) => {
let file_appender = RollingFileAppender::new(Rotation::HOURLY, "babushka-logs", file);
let _ = FILE_RELOAD
.get()
.expect("error reloading stdout")
.write()
.expect("error reloading stdout")
.modify(|layer| {
*layer.filter_mut() = level_filter;
*layer.inner_mut().writer_mut() = file_appender;
});
}
};
level
}

macro_rules! create_log {
Expand All @@ -91,10 +139,9 @@ macro_rules! create_log {
log_identifier: Identifier,
message: Message,
) {
if GUARD.read().unwrap().is_none() {
init(None, None);
if STDOUT_RELOAD.get().is_none() {
init(Some(Level::Warn), None);
};

let message_ref = message.as_ref();
let identifier_ref = log_identifier.as_ref();
event!(
Expand Down
1 change: 1 addition & 0 deletions rust-analyzer
Submodule rust-analyzer added at 67e1f5

0 comments on commit 54289da

Please sign in to comment.