From 1e4cef6e0dc5a9ad49e261c32c3c94f4b4de80dd Mon Sep 17 00:00:00 2001 From: Roland Sherwin Date: Fri, 4 Oct 2024 16:26:47 +0530 Subject: [PATCH] feat(manager): limit the max number of safenode log files --- node-launchpad/src/node_mgmt.rs | 4 + sn_logging/src/lib.rs | 20 +- sn_node/src/bin/safenode/main.rs | 24 +- sn_node_manager/src/add_services/config.rs | 14 +- sn_node_manager/src/add_services/mod.rs | 4 + sn_node_manager/src/add_services/tests.rs | 348 +++++++++++++++++++ sn_node_manager/src/bin/cli/main.rs | 15 + sn_node_manager/src/cmd/node.rs | 10 +- sn_node_manager/src/lib.rs | 381 +++++++++++++++++++++ sn_node_manager/src/local.rs | 2 + sn_node_manager/src/rpc.rs | 6 + sn_service_management/src/node.rs | 10 + 12 files changed, 814 insertions(+), 24 deletions(-) diff --git a/node-launchpad/src/node_mgmt.rs b/node-launchpad/src/node_mgmt.rs index 1b591e5a95..893523f245 100644 --- a/node-launchpad/src/node_mgmt.rs +++ b/node-launchpad/src/node_mgmt.rs @@ -297,6 +297,8 @@ async fn scale_down_nodes(config: &NodeConfig, count: u16) { None, None, None, + None, + None, None, // We don't care about the port, as we are scaling down config.owner.clone(), config.peers_args.clone(), @@ -368,6 +370,8 @@ async fn add_nodes( None, None, None, + None, + None, port_range, config.owner.clone(), config.peers_args.clone(), diff --git a/sn_logging/src/lib.rs b/sn_logging/src/lib.rs index f88463246f..e255d8c843 100644 --- a/sn_logging/src/lib.rs +++ b/sn_logging/src/lib.rs @@ -124,8 +124,8 @@ pub struct LogBuilder { default_logging_targets: Vec<(String, Level)>, output_dest: LogOutputDest, format: LogFormat, - max_uncompressed_log_files: Option, - max_compressed_log_files: Option, + max_log_files: Option, + max_archived_log_files: Option, /// Setting this would print the sn_logging related updates to stdout. print_updates_to_stdout: bool, } @@ -140,8 +140,8 @@ impl LogBuilder { default_logging_targets, output_dest: LogOutputDest::Stderr, format: LogFormat::Default, - max_uncompressed_log_files: None, - max_compressed_log_files: None, + max_log_files: None, + max_archived_log_files: None, print_updates_to_stdout: true, } } @@ -157,13 +157,13 @@ impl LogBuilder { } /// The max number of uncompressed log files to store - pub fn max_uncompressed_log_files(&mut self, files: usize) { - self.max_uncompressed_log_files = Some(files); + pub fn max_log_files(&mut self, files: usize) { + self.max_log_files = Some(files); } /// The max number of compressed files to store - pub fn max_compressed_log_files(&mut self, files: usize) { - self.max_compressed_log_files = Some(files); + pub fn max_archived_log_files(&mut self, files: usize) { + self.max_archived_log_files = Some(files); } /// Setting this to false would prevent sn_logging from printing things to stdout. @@ -182,8 +182,8 @@ impl LogBuilder { self.default_logging_targets.clone(), &self.output_dest, self.format, - self.max_uncompressed_log_files, - self.max_compressed_log_files, + self.max_log_files, + self.max_archived_log_files, self.print_updates_to_stdout, )?; diff --git a/sn_node/src/bin/safenode/main.rs b/sn_node/src/bin/safenode/main.rs index cf30e04c65..0df4c65181 100644 --- a/sn_node/src/bin/safenode/main.rs +++ b/sn_node/src/bin/safenode/main.rs @@ -107,16 +107,16 @@ struct Opt { /// /// After reaching this limit, the older files are archived to save space. /// You can also specify the maximum number of archived log files to keep. - #[clap(long = "max_log_files", verbatim_doc_comment)] - max_uncompressed_log_files: Option, + #[clap(long, verbatim_doc_comment)] + max_log_files: Option, /// Specify the maximum number of archived log files to store. /// /// This argument is ignored if `log_output_dest` is set to "stdout" /// /// After reaching this limit, the older archived files are deleted. - #[clap(long = "max_archived_log_files", verbatim_doc_comment)] - max_compressed_log_files: Option, + #[clap(long, verbatim_doc_comment)] + max_archived_log_files: Option, /// Specify the node's data directory. /// @@ -433,11 +433,11 @@ fn init_logging(opt: &Opt, peer_id: PeerId) -> Result<(String, ReloadHandle, Opt let mut log_builder = sn_logging::LogBuilder::new(logging_targets); log_builder.output_dest(output_dest.clone()); log_builder.format(opt.log_format.unwrap_or(LogFormat::Default)); - if let Some(files) = opt.max_uncompressed_log_files { - log_builder.max_uncompressed_log_files(files); + if let Some(files) = opt.max_log_files { + log_builder.max_log_files(files); } - if let Some(files) = opt.max_compressed_log_files { - log_builder.max_compressed_log_files(files); + if let Some(files) = opt.max_archived_log_files { + log_builder.max_archived_log_files(files); } log_builder.initialize()? @@ -451,11 +451,11 @@ fn init_logging(opt: &Opt, peer_id: PeerId) -> Result<(String, ReloadHandle, Opt let mut log_builder = sn_logging::LogBuilder::new(logging_targets); log_builder.output_dest(output_dest.clone()); log_builder.format(opt.log_format.unwrap_or(LogFormat::Default)); - if let Some(files) = opt.max_uncompressed_log_files { - log_builder.max_uncompressed_log_files(files); + if let Some(files) = opt.max_log_files { + log_builder.max_log_files(files); } - if let Some(files) = opt.max_compressed_log_files { - log_builder.max_compressed_log_files(files); + if let Some(files) = opt.max_archived_log_files { + log_builder.max_archived_log_files(files); } log_builder.initialize() })?; diff --git a/sn_node_manager/src/add_services/config.rs b/sn_node_manager/src/add_services/config.rs index ba0873d82c..2d5cac69dc 100644 --- a/sn_node_manager/src/add_services/config.rs +++ b/sn_node_manager/src/add_services/config.rs @@ -78,6 +78,8 @@ pub struct InstallNodeServiceCtxBuilder { pub log_dir_path: PathBuf, pub log_format: Option, pub name: String, + pub max_archived_log_files: Option, + pub max_log_files: Option, pub metrics_port: Option, pub node_ip: Option, pub node_port: Option, @@ -132,6 +134,14 @@ impl InstallNodeServiceCtxBuilder { args.push(OsString::from("--owner")); args.push(OsString::from(owner)); } + if let Some(log_files) = self.max_archived_log_files { + args.push(OsString::from("--max-archived-log-files")); + args.push(OsString::from(log_files.to_string())); + } + if let Some(log_files) = self.max_log_files { + args.push(OsString::from("--max-log-files")); + args.push(OsString::from(log_files.to_string())); + } if !self.bootstrap_peers.is_empty() { let peers_str = self @@ -169,10 +179,12 @@ pub struct AddNodeServiceOptions { pub home_network: bool, pub local: bool, pub log_format: Option, + pub max_archived_log_files: Option, + pub max_log_files: Option, pub metrics_port: Option, - pub owner: Option, pub node_ip: Option, pub node_port: Option, + pub owner: Option, pub rpc_address: Option, pub rpc_port: Option, pub safenode_src_path: PathBuf, diff --git a/sn_node_manager/src/add_services/mod.rs b/sn_node_manager/src/add_services/mod.rs index 9530f5c973..86137d881d 100644 --- a/sn_node_manager/src/add_services/mod.rs +++ b/sn_node_manager/src/add_services/mod.rs @@ -227,6 +227,8 @@ pub async fn add_node( local: options.local, log_dir_path: service_log_dir_path.clone(), log_format: options.log_format, + max_archived_log_files: options.max_archived_log_files, + max_log_files: options.max_log_files, metrics_port: metrics_free_port, name: service_name.clone(), node_ip: options.node_ip, @@ -260,6 +262,8 @@ pub async fn add_node( local: options.local, log_dir_path: service_log_dir_path.clone(), log_format: options.log_format, + max_archived_log_files: options.max_archived_log_files, + max_log_files: options.max_log_files, metrics_port: metrics_free_port, node_ip: options.node_ip, node_port, diff --git a/sn_node_manager/src/add_services/tests.rs b/sn_node_manager/src/add_services/tests.rs index fe806da6e8..f53d37f0fc 100644 --- a/sn_node_manager/src/add_services/tests.rs +++ b/sn_node_manager/src/add_services/tests.rs @@ -120,6 +120,8 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res local: true, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -154,6 +156,8 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res home_network: false, local: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -227,6 +231,8 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -272,6 +278,8 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n home_network: false, local: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -341,6 +349,8 @@ async fn add_genesis_node_should_return_an_error_if_count_is_greater_than_1() -> home_network: false, local: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -416,6 +426,8 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -454,6 +466,8 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode2"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode2".to_string(), node_ip: None, @@ -492,6 +506,8 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( local: false, log_format: None, log_dir_path: node_logs_dir.to_path_buf().join("safenode3"), + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode3".to_string(), node_ip: None, @@ -527,6 +543,8 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -651,6 +669,8 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -685,6 +705,8 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re genesis: false, home_network: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -783,6 +805,8 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -817,6 +841,8 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -889,6 +915,8 @@ async fn add_new_node_should_add_another_service() -> Result<()> { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -934,6 +962,8 @@ async fn add_new_node_should_add_another_service() -> Result<()> { local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode2"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode2".to_string(), node_ip: None, @@ -969,6 +999,8 @@ async fn add_new_node_should_add_another_service() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1105,6 +1137,8 @@ async fn add_node_should_use_custom_ip() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: Some(custom_ip), @@ -1181,6 +1215,8 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -1216,6 +1252,8 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1435,6 +1473,8 @@ async fn add_node_should_use_a_custom_port_range() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1487,6 +1527,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R local: false, log_format: None, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: Some(12000), @@ -1530,6 +1572,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1580,6 +1624,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us local: false, log_format: None, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: Some(12000), @@ -1623,6 +1669,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1690,6 +1738,8 @@ async fn add_node_should_return_an_error_if_port_and_node_count_do_not_match() - home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1762,6 +1812,8 @@ async fn add_node_should_return_an_error_if_multiple_services_are_specified_with home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1887,6 +1939,8 @@ async fn add_node_should_set_random_ports_if_enable_metrics_server_is_true() -> home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -1912,6 +1966,246 @@ async fn add_node_should_set_random_ports_if_enable_metrics_server_is_true() -> Ok(()) } +#[tokio::test] +async fn add_node_should_set_max_archived_log_files() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + bootstrap_peers: vec![], + environment_variables: None, + daemon: None, + }; + + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let safenode_download_path = temp_dir.child(SAFENODE_FILE_NAME); + safenode_download_path.write_binary(b"fake safenode bin")?; + + let mut seq = Sequence::new(); + + // Expected calls for first installation + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(8081)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("safenode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("safenode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--max-archived-log-files"), + OsString::from("20"), + ], + autostart: false, + contents: None, + environment: None, + label: "safenode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("safenode1") + .join(SAFENODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + bootstrap_peers: vec![], + count: Some(1), + delete_safenode_src: false, + enable_metrics_server: false, + env_variables: None, + genesis: false, + home_network: false, + local: false, + log_format: None, + max_archived_log_files: Some(20), + max_log_files: None, + metrics_port: None, + owner: None, + node_ip: None, + node_port: None, + rpc_address: None, + rpc_port: None, + safenode_dir_path: temp_dir.to_path_buf(), + safenode_src_path: safenode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + assert_matches!(node_registry.nodes[0].max_archived_log_files, Some(20)); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_set_max_log_files() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + bootstrap_peers: vec![], + environment_variables: None, + daemon: None, + }; + + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let safenode_download_path = temp_dir.child(SAFENODE_FILE_NAME); + safenode_download_path.write_binary(b"fake safenode bin")?; + + let mut seq = Sequence::new(); + + // Expected calls for first installation + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(8081)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("safenode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("safenode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--max-log-files"), + OsString::from("20"), + ], + autostart: false, + contents: None, + environment: None, + label: "safenode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("safenode1") + .join(SAFENODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + bootstrap_peers: vec![], + count: Some(1), + delete_safenode_src: false, + enable_metrics_server: false, + env_variables: None, + genesis: false, + home_network: false, + local: false, + log_format: None, + max_archived_log_files: None, + max_log_files: Some(20), + metrics_port: None, + owner: None, + node_ip: None, + node_port: None, + rpc_address: None, + rpc_port: None, + safenode_dir_path: temp_dir.to_path_buf(), + safenode_src_path: safenode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + assert_matches!(node_registry.nodes[0].max_log_files, Some(20)); + + Ok(()) +} + #[tokio::test] async fn add_node_should_use_a_custom_port_range_for_metrics_server() -> Result<()> { let tmp_data_dir = assert_fs::TempDir::new()?; @@ -2100,6 +2394,8 @@ async fn add_node_should_use_a_custom_port_range_for_metrics_server() -> Result< home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(PortRange::Range(12000, 12002)), owner: None, node_ip: None, @@ -2149,6 +2445,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(12000), node_ip: None, node_port: None, @@ -2192,6 +2490,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(PortRange::Single(12000)), owner: None, node_ip: None, @@ -2243,6 +2543,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(12000), node_ip: None, node_port: None, @@ -2286,6 +2588,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(PortRange::Range(12000, 12002)), owner: None, node_ip: None, @@ -2483,6 +2787,8 @@ async fn add_node_should_use_a_custom_port_range_for_the_rpc_server() -> Result< home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -2543,6 +2849,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2586,6 +2894,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -2637,6 +2947,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2680,6 +2992,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -2754,6 +3068,8 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -2788,6 +3104,8 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() genesis: false, home_network: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -2859,6 +3177,8 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -2893,6 +3213,8 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { genesis: false, home_network: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -2964,6 +3286,8 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -2998,6 +3322,8 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul genesis: false, home_network: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -3073,6 +3399,8 @@ async fn add_node_should_return_an_error_if_nat_status_is_none_but_auto_set_nat_ genesis: false, home_network: true, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -3685,6 +4013,8 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -3720,6 +4050,8 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -3792,6 +4124,8 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -3827,6 +4161,8 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( home_network: true, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -3899,6 +4235,8 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -3934,6 +4272,8 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { home_network: true, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -4003,6 +4343,8 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { local: false, log_dir_path: node_logs_dir.to_path_buf().join("safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, name: "safenode1".to_string(), node_ip: None, @@ -4038,6 +4380,8 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { home_network: true, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: None, node_ip: None, @@ -4154,6 +4498,8 @@ async fn add_node_should_assign_an_owner_in_lowercase() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: Some("Discord_Username".to_string()), node_ip: None, @@ -4272,6 +4618,8 @@ async fn add_node_should_auto_restart() -> Result<()> { home_network: false, local: false, log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, owner: Some("discord_username".to_string()), node_ip: None, diff --git a/sn_node_manager/src/bin/cli/main.rs b/sn_node_manager/src/bin/cli/main.rs index 7e89275279..3ab3b7dcea 100644 --- a/sn_node_manager/src/bin/cli/main.rs +++ b/sn_node_manager/src/bin/cli/main.rs @@ -133,6 +133,17 @@ pub enum SubCmd { /// If the argument is not used, the default format will be applied. #[clap(long, value_parser = LogFormat::parse_from_str, verbatim_doc_comment)] log_format: Option, + /// Specify the maximum number of uncompressed log files to store. + /// + /// After reaching this limit, the older files are archived to save space. + /// You can also specify the maximum number of archived log files to keep. + #[clap(long, verbatim_doc_comment)] + max_log_files: Option, + /// Specify the maximum number of archived log files to store. + /// + /// After reaching this limit, the older archived files are deleted. + #[clap(long, verbatim_doc_comment)] + max_archived_log_files: Option, /// Specify a port for the open metrics server. /// /// If you're passing the compiled safenode via --node-path, make sure to enable the open-metrics feature @@ -1026,6 +1037,8 @@ async fn main() -> Result<()> { local, log_dir_path, log_format, + max_archived_log_files, + max_log_files, metrics_port, node_ip, node_port, @@ -1050,6 +1063,8 @@ async fn main() -> Result<()> { local, log_dir_path, log_format, + max_archived_log_files, + max_log_files, metrics_port, node_ip, node_port, diff --git a/sn_node_manager/src/cmd/node.rs b/sn_node_manager/src/cmd/node.rs index 8a7ba87435..ea30532c45 100644 --- a/sn_node_manager/src/cmd/node.rs +++ b/sn_node_manager/src/cmd/node.rs @@ -46,6 +46,8 @@ pub async fn add( local: bool, log_dir_path: Option, log_format: Option, + max_archived_log_files: Option, + max_log_files: Option, metrics_port: Option, node_ip: Option, node_port: Option, @@ -145,10 +147,12 @@ pub async fn add( home_network, local, log_format, + max_archived_log_files, + max_log_files, metrics_port, - owner, node_ip, node_port, + owner, rpc_address, rpc_port, safenode_src_path, @@ -605,6 +609,8 @@ pub async fn maintain_n_running_nodes( local: bool, log_dir_path: Option, log_format: Option, + max_archived_log_files: Option, + max_log_files: Option, metrics_port: Option, node_ip: Option, node_port: Option, @@ -706,6 +712,8 @@ pub async fn maintain_n_running_nodes( local, log_dir_path.clone(), log_format, + max_archived_log_files, + max_log_files, metrics_port.clone(), node_ip, Some(PortRange::Single(port)), diff --git a/sn_node_manager/src/lib.rs b/sn_node_manager/src/lib.rs index 36a452819a..aafc905096 100644 --- a/sn_node_manager/src/lib.rs +++ b/sn_node_manager/src/lib.rs @@ -773,6 +773,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -875,6 +877,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -942,6 +946,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1052,6 +1058,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1132,6 +1140,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1222,6 +1232,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1311,6 +1323,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1370,6 +1384,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1419,6 +1435,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1466,6 +1484,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1516,6 +1536,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1579,6 +1601,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1705,6 +1729,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1793,6 +1819,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -1926,6 +1954,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2071,6 +2101,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2211,6 +2243,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2352,6 +2386,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2523,6 +2559,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2677,6 +2715,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: Some(LogFormat::Json), + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2834,6 +2874,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -2988,6 +3030,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, number: 1, node_ip: Some(Ipv4Addr::new(192, 168, 1, 1)), @@ -3145,6 +3189,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, number: 1, node_ip: None, @@ -3189,6 +3235,321 @@ mod tests { Ok(()) } + #[tokio::test] + async fn upgrade_should_retain_max_archived_log_files() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("safenode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("safenode"); + current_node_bin.write_binary(b"fake safenode binary")?; + let target_node_bin = tmp_data_dir.child("safenode"); + target_node_bin.write_binary(b"fake safenode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/safenode-manager/services/safenode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/safenode/safenode1"), + OsString::from("--max-archived-log-files"), + OsString::from("20"), + ], + autostart: false, + contents: None, + environment: None, + label: "safenode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("safe".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/safenode-manager/services/safenode1"), + log_path: PathBuf::from("/var/log/safenode/safenode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/safenode-manager/services/safenode1"), + genesis: false, + home_network: false, + listen_addr: None, + local: false, + log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), + log_format: None, + max_archived_log_files: Some(20), + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + pid: Some(1000), + reward_balance: Some(NanoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + safenode_path: current_node_bin.to_path_buf(), + service_name: "safenode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("safe".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + bootstrap_peers: Vec::new(), + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert_matches!( + service_manager.service.service_data.max_archived_log_files, + Some(20) + ); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_max_log_files() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("safenode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("safenode"); + current_node_bin.write_binary(b"fake safenode binary")?; + let target_node_bin = tmp_data_dir.child("safenode"); + target_node_bin.write_binary(b"fake safenode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/safenode-manager/services/safenode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/safenode/safenode1"), + OsString::from("--max-log-files"), + OsString::from("20"), + ], + autostart: false, + contents: None, + environment: None, + label: "safenode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("safe".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("safenode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/safenode-manager/services/safenode1"), + log_path: PathBuf::from("/var/log/safenode/safenode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/safenode-manager/services/safenode1"), + genesis: false, + home_network: false, + listen_addr: None, + local: false, + log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: Some(20), + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + pid: Some(1000), + reward_balance: Some(NanoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + safenode_path: current_node_bin.to_path_buf(), + service_name: "safenode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("safe".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + bootstrap_peers: Vec::new(), + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert_matches!(service_manager.service.service_data.max_log_files, Some(20)); + + Ok(()) + } + #[tokio::test] async fn upgrade_should_retain_custom_metrics_ports() -> Result<()> { let current_version = "0.1.0"; @@ -3299,6 +3660,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(12000), node_ip: None, node_port: None, @@ -3456,6 +3819,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: Some(12000), node_ip: None, node_port: None, @@ -3613,6 +3978,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -3770,6 +4137,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -3926,6 +4295,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -3998,6 +4369,8 @@ mod tests { local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -4055,6 +4428,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -4128,6 +4503,8 @@ mod tests { local: false, log_dir_path: PathBuf::from("/var/log/safenode/safenode1"), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -4193,6 +4570,8 @@ mod tests { local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, @@ -4256,6 +4635,8 @@ mod tests { local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, + max_archived_log_files: None, + max_log_files: None, metrics_port: None, node_ip: None, node_port: None, diff --git a/sn_node_manager/src/local.rs b/sn_node_manager/src/local.rs index ec3a7ae34e..ebff840cee 100644 --- a/sn_node_manager/src/local.rs +++ b/sn_node_manager/src/local.rs @@ -437,6 +437,8 @@ pub async fn run_node( local: true, log_dir_path: node_info.log_path, log_format: run_options.log_format, + max_archived_log_files: None, + max_log_files: None, metrics_port: run_options.metrics_port, node_ip: None, node_port: run_options.node_port, diff --git a/sn_node_manager/src/rpc.rs b/sn_node_manager/src/rpc.rs index 2c8f15a88b..b9fc50ced8 100644 --- a/sn_node_manager/src/rpc.rs +++ b/sn_node_manager/src/rpc.rs @@ -71,6 +71,8 @@ pub async fn restart_node_service( local: current_node_clone.local, log_dir_path: current_node_clone.log_dir_path.clone(), log_format: current_node_clone.log_format, + max_archived_log_files: current_node_clone.max_archived_log_files, + max_log_files: current_node_clone.max_log_files, metrics_port: None, owner: current_node_clone.owner.clone(), name: current_node_clone.service_name.clone(), @@ -188,6 +190,8 @@ pub async fn restart_node_service( log_dir_path: log_dir_path.clone(), log_format: current_node_clone.log_format, name: new_service_name.clone(), + max_archived_log_files: current_node_clone.max_archived_log_files, + max_log_files: current_node_clone.max_log_files, metrics_port: None, node_ip: current_node_clone.node_ip, node_port: None, @@ -212,6 +216,8 @@ pub async fn restart_node_service( local: current_node_clone.local, log_dir_path, log_format: current_node_clone.log_format, + max_archived_log_files: current_node_clone.max_archived_log_files, + max_log_files: current_node_clone.max_log_files, metrics_port: None, node_ip: current_node_clone.node_ip, node_port: None, diff --git a/sn_service_management/src/node.rs b/sn_service_management/src/node.rs index ffd6af0742..107b01d635 100644 --- a/sn_service_management/src/node.rs +++ b/sn_service_management/src/node.rs @@ -101,6 +101,14 @@ impl<'a> ServiceStateActions for NodeService<'a> { args.push(OsString::from("--metrics-server-port")); args.push(OsString::from(metrics_port.to_string())); } + if let Some(max_archived_log_files) = self.service_data.max_archived_log_files { + args.push(OsString::from("--max-archived-log-files")); + args.push(OsString::from(max_archived_log_files.to_string())); + } + if let Some(max_log_files) = self.service_data.max_log_files { + args.push(OsString::from("--max-log-files")); + args.push(OsString::from(max_log_files.to_string())); + } if let Some(owner) = &self.service_data.owner { args.push(OsString::from("--owner")); @@ -267,6 +275,8 @@ pub struct NodeServiceData { pub local: bool, pub log_dir_path: PathBuf, pub log_format: Option, + pub max_archived_log_files: Option, + pub max_log_files: Option, #[serde(default)] pub metrics_port: Option, #[serde(default)]