From 9a0e1c1b0e920bebc84b7bc2573b1eae4e2f36c9 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Wed, 6 May 2020 21:05:51 +0800 Subject: [PATCH] add file rotation --- src/logger.rs | 83 ++++++++++++++++++++++++-------------------------- src/options.rs | 13 +++++--- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/logger.rs b/src/logger.rs index 49899b9..08421ea 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -24,13 +24,12 @@ use std::sync::Mutex; /// /// See `slog` at https://github.com/slog-rs/slog /// See `log` at https://github.com/rust-lang/log -/// +/// -fn create_file(storage:&S,dp_path:&str,timestamp:i64) -> Result { - let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); - storage.rename(dp_path, new_path.as_str())?; - storage.create(dp_path) - +fn create_file(storage: &S, dp_path: &str, timestamp: i64) -> Result { + let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); + storage.rename(dp_path, new_path.as_str())?; + storage.create(dp_path) } pub struct Logger { @@ -45,10 +44,10 @@ impl Logger { /// If `inner` is `None` /// - In dev mode, use a std output /// - In release mode, use a storage specific file with name `LOG` - pub fn new( + pub fn new( inner: Option, level: LevelFilter, - storage:S, + storage: S, db_path: String, ) -> Self { let inner = match inner { @@ -62,12 +61,13 @@ impl Logger { } else { // Use a file `Log` to record all logs // TODO: add file rotation - let file = create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); - let file_fn = move|path:String| {create_file(&storage, - path.as_str(),Local::now().timestamp())}; - let drain =FileBasedDrain::new(file,db_path.clone(), - file_fn) - .add_rotator(RotatedFileBySize::new(0)); + let file = + create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); + let file_fn = move |path: String| { + create_file(&storage, path.as_str(), Local::now().timestamp()) + }; + let drain = FileBasedDrain::new(file, db_path, file_fn) + .add_rotator(RotatedFileBySize::new(0)); let drain = slog_async::Async::new(drain).build().fuse(); slog::Logger::root(drain, o!()) } @@ -128,36 +128,37 @@ fn log_to_slog_level(level: log::Level) -> Level { } } -struct FileBasedDrain { +struct FileBasedDrain { inner: Mutex, rotators: Vec>, - dp_path:String, - new_file:BoxResult> + dp_path: String, + new_file: Box Result>, } -impl FileBasedDrain { - fn new(f:F,path:String,new_file: H) -> Self - where H:'static+Send+Fn(String)->Result - { +impl FileBasedDrain { + fn new(f: F, path: String, new_file: H) -> Self + where + H: 'static + Send + Fn(String) -> Result, + { FileBasedDrain { - dp_path: path.clone(), + dp_path: path, inner: Mutex::new(f), rotators: vec![], - new_file:Box::new(new_file) + new_file: Box::new(new_file), } } - fn add_rotator(mut self, rotator: R) -> Self { + fn add_rotator(mut self, rotator: R) -> Self { if rotator.is_enabled() { self.rotators.push(Box::new(rotator)); } - for rotator in (&self).rotators.iter() { + for rotator in self.rotators.iter() { rotator.prepare(&*self.inner.lock().unwrap()).unwrap(); } self } - fn flush(&self) ->Result<()>{ + fn flush(&self) -> Result<()> { self.inner.lock().unwrap().flush()?; let new_file = (self.new_file)(self.dp_path.clone()).unwrap(); @@ -166,12 +167,11 @@ impl FileBasedDrain { for rotator in self.rotators.iter() { rotator.on_rotate()?; } - return Ok(()); - + Ok(()) } } -impl Drain for FileBasedDrain { +impl Drain for FileBasedDrain { type Ok = (); type Err = slog::Never; @@ -186,13 +186,13 @@ impl Drain for FileBasedDrain { record.msg(), values ); - for rotator in self.rotators.iter() { - if rotator.should_rotate() { - self.flush().unwrap(); - return Ok(()); - } - } - + for rotator in self.rotators.iter() { + if rotator.should_rotate() { + self.flush().unwrap(); + return Ok(()); + } + } + for rotator in self.rotators.iter() { rotator.on_write(by.as_bytes()).unwrap(); } @@ -203,8 +203,6 @@ impl Drain for FileBasedDrain { } } - - trait Rotator: Send { /// Check if the option is enabled in configuration. /// Return true if the `rotator` is valid. @@ -239,10 +237,9 @@ impl Rotator for RotatedFileBySize { fn is_enabled(&self) -> bool { self.rotation_size != 0 } - fn prepare(&self, file: &dyn File) -> Result<()> { + fn prepare(&self, file: &dyn File) -> Result<()> { *self.file_size.lock().unwrap() = file.len().unwrap(); Ok(()) - } fn should_rotate(&self) -> bool { @@ -266,11 +263,11 @@ mod tests { use crate::storage::mem::MemStorage; use std::thread; - use std::time::Duration; - + use std::time::Duration; + #[test] fn test_default_logger() { - let s =MemStorage::default(); + let s = MemStorage::default(); // let s = &'static s; let db_path = "test"; let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string()); diff --git a/src/options.rs b/src/options.rs index cedf93d..a3d3b88 100644 --- a/src/options.rs +++ b/src/options.rs @@ -205,10 +205,10 @@ impl Options { } /// Initialize Options by limiting ranges of some flags, applying customized Logger and etc. - pub(crate) fn initialize+Clone+'static>( + pub(crate) fn initialize + Clone + 'static>( &mut self, db_name: String, - storage: &S, + storage: &S, ) { self.max_open_files = Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000); @@ -225,9 +225,14 @@ impl Options { } #[allow(unused_must_use)] - fn apply_logger(&mut self, storage: &S, db_path: &str) { + fn apply_logger(&mut self, storage: &S, db_path: &str) { let user_logger = std::mem::replace(&mut self.logger, None); - let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path.to_string()); + let logger = Logger::new( + user_logger, + self.logger_level, + storage.clone(), + db_path.to_string(), + ); let static_logger: &'static dyn Log = Box::leak(Box::new(logger)); log::set_logger(static_logger); log::set_max_level(self.logger_level);