From 8b9ac4b0954529df5c343317ee5223307224303c Mon Sep 17 00:00:00 2001 From: licunlong Date: Sun, 25 Jun 2023 15:00:41 +0800 Subject: [PATCH] feature: use LogFileSize and LogFileNumber to rotate the log and make __um_obj_create() accept LogFileSize/LogFileNumber --- core/bin/plugin/mod.rs | 61 ++++++++++++++++------------ core/bin/unit/manager.rs | 25 ++++++++---- core/lib/unit/umif.rs | 6 ++- libs/basic/src/logger.rs | 88 +++++++++++++++++++++++++++++++--------- 4 files changed, 125 insertions(+), 55 deletions(-) diff --git a/core/bin/plugin/mod.rs b/core/bin/plugin/mod.rs index 9b19336..a8f6f24 100644 --- a/core/bin/plugin/mod.rs +++ b/core/bin/plugin/mod.rs @@ -475,33 +475,44 @@ impl Plugin { unit_type: UnitType, target: &str, file: &str, + file_size: u32, + file_number: u32, ) -> Result> { - match self.get_lib(unit_type) { - Ok(dy_lib) => { - #[allow(clippy::type_complexity)] - let sym: Result< - Symbol< - fn(level: LevelFilter, target: &str, file: &str) -> *mut dyn UnitManagerObj, - >, - > = unsafe { - dy_lib - .lib - .get(b"__um_obj_create") - .map_err(|e| Error::PluginLoad { msg: e.to_string() }) - }; - if let Ok(fun) = sym { - let boxed_raw = fun(log::max_level(), target, file); - Ok(unsafe { Box::from_raw(boxed_raw) }) - } else { - Err(Error::PluginLoad { - msg: format!("The library of {:?} is {:?}", unit_type, sym.err()), - }) - } + let dy_lib = match self.get_lib(unit_type) { + Err(_) => { + return Err(Error::PluginLoad { + msg: format!("create um, the {unit_type:?} plugin is not exist"), + }); } - Err(_) => Err(Error::PluginLoad { - msg: format!("create um, the {unit_type:?} plugin is not exist"), - }), - } + Ok(v) => v, + }; + + type FnType = fn( + level: LevelFilter, + target: &str, + file: &str, + file_size: u32, + file_number: u32, + ) -> *mut dyn UnitManagerObj; + + #[allow(clippy::type_complexity)] + let sym: Result> = unsafe { + dy_lib + .lib + .get(b"__um_obj_create") + .map_err(|e| Error::PluginLoad { msg: e.to_string() }) + }; + let fun = match sym { + Err(_) => { + return Err(Error::PluginLoad { + msg: format!("The library of {:?} is {:?}", unit_type, sym.err()), + }) + } + Ok(v) => v, + }; + + let boxed_raw = fun(log::max_level(), target, file, file_size, file_number); + Ok(unsafe { Box::from_raw(boxed_raw) }) } fn get_lib(&self, unit_type: UnitType) -> Result> { diff --git a/core/bin/unit/manager.rs b/core/bin/unit/manager.rs index 492f3f4..f548817 100644 --- a/core/bin/unit/manager.rs +++ b/core/bin/unit/manager.rs @@ -1408,15 +1408,24 @@ mod unit_submanager { fn new_sub(&self, unit_type: UnitType) -> Option> { let um = self.um(); - let target = um.get_log_target(); - let file = um.get_log_file(); - let ret = Plugin::get_instance().create_um_obj(unit_type, target, file); - if ret.is_err() { - log::info!("create um_obj is not found, type {:?}!", unit_type); - return None; - } + log::info!( + "Creating UnitManagerObj for {:?} by __um_obj_create()", + unit_type + ); + let sub = match Plugin::get_instance().create_um_obj( + unit_type, + um.get_log_target(), + um.get_log_file(), + um.get_log_file_size(), + um.get_log_file_number(), + ) { + Err(_) => { + log::info!("__um_obj_create() of {:?} is not found", unit_type); + return None; + } + Ok(v) => v, + }; - let sub = ret.unwrap(); let reli = um.reliability(); sub.attach_um(um); sub.attach_reli(reli); diff --git a/core/lib/unit/umif.rs b/core/lib/unit/umif.rs index c41c211..a000a3d 100644 --- a/core/lib/unit/umif.rs +++ b/core/lib/unit/umif.rs @@ -250,9 +250,11 @@ macro_rules! declure_umobj_plugin { pub fn __um_obj_create( level: LevelFilter, target: &str, - file: &str, + file_path: &str, + file_size: u32, + file_number: u32, ) -> *mut dyn $crate::unit::UnitManagerObj { - logger::init_log_for_subum($name, level, target, file); + logger::init_log_for_subum($name, level, target, file_path, file_size, file_number); let construcotr: fn() -> $unit_type = $constructor; let obj = construcotr(); let boxed: Box = Box::new(obj); diff --git a/libs/basic/src/logger.rs b/libs/basic/src/logger.rs index 2f24d25..0bc15bb 100644 --- a/libs/basic/src/logger.rs +++ b/libs/basic/src/logger.rs @@ -15,7 +15,12 @@ use log::{LevelFilter, Log}; use log4rs::{ append::{ console::{ConsoleAppender, Target}, - file::FileAppender, + rolling_file::{ + policy::compound::{ + roll::fixed_window::FixedWindowRoller, trigger::size::SizeTrigger, CompoundPolicy, + }, + RollingFileAppender, + }, Append, }, config::{Appender, Config, Logger, Root}, @@ -78,13 +83,20 @@ impl log::Log for SysLogger { fn flush(&self) {} } -fn append_log(app_name: &str, level: LevelFilter, target: &str, file_path: Option<&str>) { +fn append_log( + app_name: &str, + level: LevelFilter, + target: &str, + file_path: &str, + file_size: u32, + file_number: u32, +) { if target == "syslog" { let _ = log::set_boxed_logger(Box::new(SysLogger)); log::set_max_level(level); return; } - let config = build_log_config(app_name, level, target, file_path); + let config = build_log_config(app_name, level, target, file_path, file_size, file_number); let logger = log4rs::Logger::new(config); log::set_max_level(level); let _ = log::set_boxed_logger(Box::new(LogPlugin(logger))); @@ -99,12 +111,18 @@ fn append_log(app_name: &str, level: LevelFilter, target: &str, file_path: Optio /// target: log target /// /// file_path: file path if the target is set to file -pub fn init_log_for_subum(app_name: &str, level: LevelFilter, target: &str, file: &str) { - let file = if file.is_empty() { None } else { Some(file) }; +pub fn init_log_for_subum( + app_name: &str, + level: LevelFilter, + target: &str, + file_path: &str, + file_size: u32, + file_number: u32, +) { /* We should avoid calling init_log here, or we will get many "attempted * to set a logger after the logging system was already initialized" error * message. */ - append_log(app_name, level, target, file); + append_log(app_name, level, target, file_path, file_size, file_number); } /// Init and set the log target to console @@ -113,7 +131,7 @@ pub fn init_log_for_subum(app_name: &str, level: LevelFilter, target: &str, file /// /// level: maximum log level pub fn init_log_to_console(app_name: &str, level: LevelFilter) { - init_log(app_name, level, "console", None); + init_log(app_name, level, "console", "", 0, 0); } /// Init and set the log target to file @@ -123,8 +141,14 @@ pub fn init_log_to_console(app_name: &str, level: LevelFilter) { /// level: maximum log level /// /// file_path: log to which file -pub fn init_log_to_file(app_name: &str, level: LevelFilter, file_path: &str) { - init_log(app_name, level, "file", Some(file_path)); +pub fn init_log_to_file( + app_name: &str, + level: LevelFilter, + file_path: &str, + file_size: u32, + file_number: u32, +) { + init_log(app_name, level, "file", file_path, file_size, file_number); } /// Init and set the logger @@ -136,13 +160,20 @@ pub fn init_log_to_file(app_name: &str, level: LevelFilter, file_path: &str) { /// target: log target /// /// file_path: file path if the target is set to file -pub fn init_log(app_name: &str, level: LevelFilter, target: &str, file_path: Option<&str>) { +pub fn init_log( + app_name: &str, + level: LevelFilter, + target: &str, + file_path: &str, + file_size: u32, + file_number: u32, +) { if target == "syslog" { let _ = log::set_boxed_logger(Box::new(SysLogger)); log::set_max_level(level); return; } - let config = build_log_config(app_name, level, target, file_path); + let config = build_log_config(app_name, level, target, file_path, file_size, file_number); let r = log4rs::init_config(config); if let Err(e) = r { println!("{e}"); @@ -153,12 +184,18 @@ fn build_log_config( app_name: &str, level: LevelFilter, target: &str, - file: Option<&str>, + file_path: &str, + file_size: u32, + file_number: u32, ) -> Config { let mut target = target; /* If the file is configured to None, use console forcely. */ - if file.is_none() && target == "file" { - println!("LogTarget is configured to `file`, but LogFile is not configured, changing the LogTarget to `console`"); + if (file_path.is_empty() || file_size == 0 || file_number == 0) && target == "file" { + println!( + "LogTarget is configured to `file`, but configuration is invalid, changing the \ + LogTarget to `console`, file: {file_path}, file_size: {file_size}, file_number: \ + {file_number}" + ); target = "console"; } let encoder = Box::new(PatternEncoder::new(LOG_PATTERN)); @@ -169,12 +206,23 @@ fn build_log_config( .target(Target::Stdout) .build(), ), - "file" => Box::new( - FileAppender::builder() - .encoder(encoder) - .build(file.unwrap()) - .unwrap(), - ), + "file" => { + let pattern = file_path.to_string() + &".{}"; + let policy = Box::new(CompoundPolicy::new( + Box::new(SizeTrigger::new(file_size as u64 * 1024)), + Box::new( + FixedWindowRoller::builder() + .build(&pattern, file_number) + .unwrap(), + ), + )); + Box::new( + RollingFileAppender::builder() + .encoder(encoder) + .build(file_path, policy) + .unwrap(), + ) + } _ => Box::new( ConsoleAppender::builder() .encoder(encoder) -- 2.33.0