diff --git a/.gitignore b/.gitignore index d01bd1a..1f29c15 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ Cargo.lock # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +.vscode/ +bin/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 9e2d261..e38d263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "doh" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "GNU GPLv3" repository = "https://github.com/ZimaBlue-AI/DoH" diff --git a/LANG b/LANG new file mode 100644 index 0000000..061c2a6 --- /dev/null +++ b/LANG @@ -0,0 +1,15 @@ +=============================================================================== + Language Files Lines Code Comments Blanks +=============================================================================== + JSON 3 174 174 0 0 + Rust 7 1574 1349 76 149 + Shell 1 12 9 3 0 + TOML 1 38 34 0 4 +------------------------------------------------------------------------------- + Markdown 1 61 0 41 20 + |- BASH 1 14 12 2 0 + |- JSON 1 133 133 0 0 + (Total) 208 145 43 20 +=============================================================================== + Total 13 1859 1566 120 173 +=============================================================================== diff --git a/README.md b/README.md index ef71256..3f80637 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,16 @@ cargo build --release "job_monitor": { "check_interval": 10, "script_path": "/mnt/c/DoH/test.sh", # run job shell script + "init_condition": { + "cpu_idle_rate_threshold": 0.5, + "available_memory_threshold": 2147483648, + "path_space": [ + { + "path":"/mnt/c/DoH/", + "space_threshold":[0, 4294967296] + } + ] + }, "receiver": [{ "receive_id": "ou_***", "receive_id_type": "open_id" diff --git a/config.json b/config.json index 1bf29a5..b2df820 100644 --- a/config.json +++ b/config.json @@ -6,7 +6,7 @@ "path_space": [ { "path":"/mnt/c/DoH/", - "space_threshold":[10, 26214400] + "space_threshold":[10, 4294967296] } ], "receiver": [{ @@ -39,7 +39,18 @@ }, "job_monitor": { "check_interval": 10, - "script_path": "/mnt/c/DoH/test/test.sh", + "script_path": "/mnt/c/DoH/test/test.sh", + "init_condition": { + "cpu_idle_rate_threshold": 0.5, + "available_memory_threshold": 2147483648, + "path_space": [ + { + "path":"/mnt/c/DoH/", + "space_threshold":[0, 4294967296] + } + ] + + }, "receiver": [{ "receive_id": "ou_***", "receive_id_type": "open_id" diff --git a/src/disk_monitor.rs b/src/disk_monitor.rs index 145dc7b..f80c1b9 100644 --- a/src/disk_monitor.rs +++ b/src/disk_monitor.rs @@ -1,4 +1,3 @@ -// use serde::Deserialize; use std::fs; use std::thread; use std::time::Duration; diff --git a/src/job_monitor.rs b/src/job_monitor.rs index b8f3a16..3fd5c7e 100644 --- a/src/job_monitor.rs +++ b/src/job_monitor.rs @@ -25,6 +25,75 @@ async fn main() { let current_process_pid = sysinfo::get_current_pid().expect("Failed to get current PID"); + let init_condition = &config.job_monitor.init_condition; + + let mut init_job_pass_throught = false; + + // 检查资源起始条件 + while !init_job_pass_throught { + let mut sys = System::new_all(); + sys.refresh_all(); + // 检查 CPU 空闲 + let mut total_cpu_usage = 0.0; + for cpu in sys.cpus() { + total_cpu_usage += cpu.cpu_usage(); + } + let total_cpu_usage_rate = total_cpu_usage / sys.cpus().len() as f32; + let cpu_idle_rate = 100.0 - total_cpu_usage_rate; + if cpu_idle_rate < init_condition.cpu_idle_rate_threshold { + warn!("CPU idle is below the threshold: {}%", cpu_idle_rate); + init_job_pass_throught = false; + } else { + init_job_pass_throught = true; + } + + if !init_job_pass_throught { + sleep(Duration::from_secs(1)).await; + continue; + } + + // 检查 RAM 可用内存 + let available_memory = sys.free_memory(); + if available_memory < init_condition.available_memory_threshold { + warn!("Available memory is below the threshold: {}", format_bytes(available_memory)); + init_job_pass_throught = false; + } else { + init_job_pass_throught = true; + } + if !init_job_pass_throught { + sleep(Duration::from_secs(1)).await; + continue; + } + + // 检查指定路径所在磁盘空间 + for path_space in &init_condition.path_space { + let path = &path_space.path; + let space_threshold = path_space.space_threshold; + if let Ok(metadata) = fs::metadata(path) { + if metadata.is_dir() { + let total_size = get_dir_size(path); + if total_size > space_threshold.1 || total_size < space_threshold.0 { + warn!("Directory size exceeds threshold in path {:?}: {}", path, format_bytes(total_size)); + init_job_pass_throught = false; + } else { + init_job_pass_throught = true; + } + } else { + if metadata.len() > space_threshold.1 || metadata.len() < space_threshold.0 { + warn!("File size exceeds threshold in path {:?}: {}", path, format_bytes(metadata.len())); + init_job_pass_throught = false; + } else { + init_job_pass_throught = true; + } + } + } + } + if !init_job_pass_throught { + sleep(Duration::from_secs(1)).await; + continue; + } + } + // 启动 shell 脚本 let start_time = SystemTime::now(); let script_path = &config.job_monitor.script_path; @@ -32,6 +101,9 @@ async fn main() { .arg(script_path) .spawn() .expect("Failed to start script"); + // 检查资源起始条件 + let mut sys = System::new_all(); + sys.refresh_all(); let pid = child.id(); info!("Started script (script: {}) with PID: {}", script_path, pid); diff --git a/src/lib.rs b/src/lib.rs index 6c777e3..ddfc756 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,7 +72,8 @@ pub struct NodeMonitorConfig { pub struct JobMonitorConfig { pub check_interval: u64, pub script_path: String, - pub receiver: Vec + pub receiver: Vec, + pub init_condition: InitConditionConfig } #[derive(Deserialize, Clone, PartialEq)] @@ -81,6 +82,13 @@ pub struct ReceiverConfig { pub receive_id_type: String, } +#[derive(Deserialize, Clone)] +pub struct InitConditionConfig { + pub cpu_idle_rate_threshold: f32, + pub available_memory_threshold: u64, + pub path_space: Vec +} + #[derive(Serialize, Deserialize, Debug, Clone)] struct MsgPayload { content: String, diff --git a/src/network_monitor.rs b/src/network_monitor.rs index 2d9fef7..5040721 100644 --- a/src/network_monitor.rs +++ b/src/network_monitor.rs @@ -30,22 +30,22 @@ pub async fn start_network_monitor(config_path: &str) { // Print Network information info!("Network Information:"); let networks = Networks::new_with_refreshed_list(); - for (interface_name, network) in &networks { - if network.received() > net_config.data_threshold || network.transmitted() > net_config.data_threshold { + for (interface_name, data) in &networks { + if data.received() > net_config.data_threshold || data.transmitted() > net_config.data_threshold { warn!( "Warning: {} received {}, transmitted {}", interface_name, - format_bytes(network.received()), - format_bytes(network.transmitted()) + format_bytes(data.received()), + format_bytes(data.transmitted()) ); - warn!("Ip Networks: {:?}", network.ip_networks()); + warn!("Ip Networks: {:?}", data.ip_networks()); msg_content.push_str(&format!("Warning: {} received {}, transmitted {}\n", interface_name, - format_bytes(network.received()), - format_bytes(network.transmitted()) + format_bytes(data.received()), + format_bytes(data.transmitted()) )); - msg_content.push_str(&format!("Ip Networks: {:?}\n", network.ip_networks())); + msg_content.push_str(&format!("Ip Networks: {:?}\n", data.ip_networks())); } } @@ -72,6 +72,7 @@ pub async fn start_network_monitor(config_path: &str) { } } + //TODO: write a function to get the socket info info!("--------------------------------TCP--------------------------------"); let mut msg_content_title = format!("--------------------------------TCP--------------------------------\n"); // get the tcp table diff --git a/src/resource_monitor.rs b/src/resource_monitor.rs index 04ba42b..7eb50e9 100644 --- a/src/resource_monitor.rs +++ b/src/resource_monitor.rs @@ -1,5 +1,3 @@ -// use serde::Deserialize; -// use std::fs; use std::thread; use std::time::Duration; use sysinfo::{System, Users, Pid};