diff --git a/Cargo.lock b/Cargo.lock index be03c38..394ea41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,7 +91,7 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cai-watchdog" -version = "0.8.0" +version = "0.9.0" dependencies = [ "chrono", "exitcode", diff --git a/Cargo.toml b/Cargo.toml index 9609711..c6be4c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cai-watchdog" -version = "0.8.0" +version = "0.9.0" authors = ["Alexander I. Chebykin "] edition = "2018" diff --git a/src/main.rs b/src/main.rs index 9b76195..8b13b18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,31 +8,17 @@ extern crate exitcode; use std::env; use std::ffi::OsStr; use std::path::Path; -use std::process::Command; use std::thread; use std::time::Duration; use sysinfo::System; mod mods; +use crate::mods::mod_debug::*; use crate::mods::mod_fs::*; -use crate::mods::mod_locales::*; - -/// Rule description structure -struct Rule { - /// Monitored service name - pub service: String, - /// Monitored URI - pub uri: String, - /// Monitored process name - pub process: String, - /// E-mail address for messages - pub email: String, - /// This command will be executed on state change - pub command: String, - /// Last state - pub last_state: bool, -} +use crate::mods::mod_i18n::*; +use crate::mods::mod_os::*; +use crate::mods::mod_tasks::*; /// Check rule /// @@ -108,59 +94,6 @@ async fn check_uri(uri: String) -> bool { } } -/// Output to console only in debug version -/// -/// # Arguments -/// -/// * `text` - Message text -/// -/// # Example -/// -/// ``` -/// debug_log("Debug version started".to_string()); -/// ``` -fn debug_log(text: String) { - if cfg!(debug_assertions) { - println!("{}", text); - } -} - -/// Execute shell command -/// -/// In linux sh command interpreter will be called. -/// In Windows PowerShell command interpreter will be called. -/// -/// # Arguments -/// -/// * `command` - Command to be executed -/// -/// # Example -/// -/// ``` -/// execute("gedit".to_string()); -/// ``` -fn execute(command: String) { - let locale = Locale::new(); - - debug_log(format!("{} {}", locale.t().execute, command)); - - let output = if cfg!(target_os = "windows") { - Command::new("powershell") - .args(["-NoLogo", "-NonInteractive", "-Command", &command]) - .output() - .expect(&locale.t().failed_to_execute_process) //.expect("failed to execute process") - } else { - Command::new("sh") - .arg("-c") - .arg(&command) - .output() - .expect(&locale.t().failed_to_execute_process) //.expect("failed to execute process") - }; - - let result = output.stdout; - debug_log(format!("{:?}", result)); -} - /// Print help and program version information /// /// # Arguments @@ -352,95 +285,10 @@ fn main() { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - //if check(tasks[i].uri.clone()).await { if check(&tasks_web[i]).await { - if tasks_web[i].last_state != true || just_started_web { - if tasks_web[i].command.to_string() == "".to_string() { - println!("\u{2705} {} {}", - tasks_web[i].uri, - locale.t().state_changed_to_true - ); - } else { - debug_log(format!("\u{2705} {} {}", - tasks_web[i].uri, - locale.t().state_changed_to_true) - ); - - let shell_cmd = - tasks_web[i].command.to_string() - .replace("", &tasks_web[i].email) - .replace("", - &format!( - "\"\u{2705} {} {} ({}) {}\"", - locale.t().service, - tasks_web[i].service, - tasks_web[i].uri, - locale.t().is_online - ) - ) - .replace("", - &format!( - "\"\u{2705} {} {} ({}) {}\"", - locale.t().service, - tasks_web[i].service, - tasks_web[i].uri, - locale.t().is_online_now - ) - ) - .replace("", &tasks_web[i].service) - .replace("", &tasks_web[i].uri) - .replace("", "online"); - - debug_log(format!("{} {}", locale.t().execute, shell_cmd)); - - execute(shell_cmd); - } - } - - debug_log(format!("\u{2705} {} {}", tasks_web[i].uri, locale.t().check_is_ok)); - - tasks_web[i].last_state = true; + execute_web_task(&mut tasks_web[i], true, just_started_web); } else { - if tasks_web[i].last_state != false || just_started_web { - if tasks_web[i].command.to_string() == "".to_string() { - println!("\u{274c} {} {}", tasks_web[i].uri, locale.t().state_changed_to_false); - } else { - debug_log(format!("\u{274c} {} {}", tasks_web[i].uri, locale.t().state_changed_to_false)); - - let shell_cmd = - tasks_web[i].command.to_string() - .replace("", &tasks_web[i].email) - .replace("", & - format!( - "\"\u{274c} {} {} ({}) {}\"", - locale.t().service, - tasks_web[i].service, - tasks_web[i].uri, - locale.t().is_offline - ) - ) - .replace("", & - format!( - "\"\u{274c} {} {} ({}) {}\"", - locale.t().service, - tasks_web[i].service, - tasks_web[i].uri, - locale.t().is_offline_now - ) - ) - .replace("", &tasks_web[i].service) - .replace("", &tasks_web[i].uri) - .replace("", "offline"); - - debug_log(format!("{} {}", locale.t().execute, shell_cmd)); - - execute(shell_cmd); - } - } - - debug_log(format!("\u{274c} {} {}", tasks_web[i].uri, locale.t().check_failed)); - - tasks_web[i].last_state = false; + execute_web_task(&mut tasks_web[i], false, just_started_web); } }); } @@ -453,96 +301,15 @@ fn main() { let mut just_started_prc = true; - let locale = Locale::new(); - loop { for i in 0..tasks_prc.len() { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - //if check(tasks[i].uri.clone()).await { if check(&tasks_prc[i]).await { - if tasks_prc[i].last_state != true || just_started_prc { - if tasks_prc[i].command.to_string() == "".to_string() { - println!("\u{2705} {} {}", tasks_prc[i].uri, locale.t().state_changed_to_true); - } else { - debug_log(format!("\u{2705} {} {}", tasks_prc[i].uri, locale.t().state_changed_to_true)); - - let shell_cmd = - tasks_prc[i].command.to_string() - .replace("", &tasks_prc[i].email) - .replace("", - &format!( - "\"\u{2705} {} {} ({}) {}\"", - locale.t().process, - tasks_prc[i].service, - tasks_prc[i].process, - locale.t().is_running - ) - ) - .replace("", - &format!( - "\"\u{2705} {} {} ({}) {}\"", - locale.t().process, - tasks_prc[i].service, - tasks_prc[i].process, - locale.t().is_running_now - ) - ) - .replace("", &tasks_prc[i].service) - .replace("", &tasks_prc[i].process) - .replace("", "running"); - - debug_log(format!("{} {}", locale.t().execute, shell_cmd)); - - execute(shell_cmd); - } - } - - debug_log(format!("\u{2705} {} {}", tasks_prc[i].process, locale.t().is_running)); - - tasks_prc[i].last_state = true; + execute_os_task(&mut tasks_prc[i], true, just_started_prc); } else { - if tasks_prc[i].last_state != false || just_started_prc { - if tasks_prc[i].command.to_string() == "".to_string() { - println!("\u{274c} {} {}", tasks_prc[i].uri, locale.t().state_changed_to_false); - } else { - debug_log(format!("\u{274c} {} {}", tasks_prc[i].uri, locale.t().state_changed_to_false)); - - let shell_cmd = - tasks_prc[i].command.to_string() - .replace("", &tasks_prc[i].email) - .replace("", - &format!( - "\"\u{274c} {} {} ({}) {}\"", - locale.t().process, - tasks_prc[i].service, - tasks_prc[i].process, - locale.t().is_not_running - ) - ) - .replace("", - &format!( - "\"\u{274c} {} {} ({}) {}\"", - locale.t().process, - tasks_prc[i].service, - tasks_prc[i].process, - locale.t().is_not_running_now - ) - ) - .replace("", &tasks_prc[i].service) - .replace("", &tasks_prc[i].process) - .replace("", "stopped"); - - debug_log(format!("{} {}", locale.t().execute, shell_cmd)); - execute(shell_cmd); - } - } - - debug_log(format!("\u{274c} {} {}", tasks_prc[i].process, locale.t().is_not_running)); - - - tasks_prc[i].last_state = false; + execute_os_task(&mut tasks_prc[i], false, just_started_prc); } }); } diff --git a/src/mods/mod.rs b/src/mods/mod.rs index 08e9392..01cea12 100644 --- a/src/mods/mod.rs +++ b/src/mods/mod.rs @@ -1,2 +1,5 @@ +pub mod mod_debug; pub mod mod_fs; -pub mod mod_locales; +pub mod mod_i18n; +pub mod mod_os; +pub mod mod_tasks; \ No newline at end of file diff --git a/src/mods/mod_debug.rs b/src/mods/mod_debug.rs new file mode 100644 index 0000000..847a14f --- /dev/null +++ b/src/mods/mod_debug.rs @@ -0,0 +1,16 @@ +/// Output to console only in debug version +/// +/// # Arguments +/// +/// * `text` - Message text +/// +/// # Example +/// +/// ``` +/// debug_log("Debug version started".to_string()); +/// ``` +pub fn debug_log(text: String) { + if cfg!(debug_assertions) { + println!("{}", text); + } +} diff --git a/src/mods/mod_locales.rs b/src/mods/mod_i18n.rs similarity index 100% rename from src/mods/mod_locales.rs rename to src/mods/mod_i18n.rs diff --git a/src/mods/mod_os.rs b/src/mods/mod_os.rs new file mode 100644 index 0000000..21cf894 --- /dev/null +++ b/src/mods/mod_os.rs @@ -0,0 +1,40 @@ +use std::process::Command; + +use crate::mods::mod_debug::*; +use crate::mods::mod_i18n::*; + +/// Execute shell command +/// +/// In linux sh command interpreter will be called. +/// In Windows PowerShell command interpreter will be called. +/// +/// # Arguments +/// +/// * `command` - Command to be executed +/// +/// # Example +/// +/// ``` +/// execute("gedit".to_string()); +/// ``` +pub fn execute(command: String) { + let locale = Locale::new(); + + debug_log(format!("{} {}", locale.t().execute, command)); + + let output = if cfg!(target_os = "windows") { + Command::new("powershell") + .args(["-NoLogo", "-NonInteractive", "-Command", &command]) + .output() + .expect(&locale.t().failed_to_execute_process) //.expect("failed to execute process") + } else { + Command::new("sh") + .arg("-c") + .arg(&command) + .output() + .expect(&locale.t().failed_to_execute_process) //.expect("failed to execute process") + }; + + let result = output.stdout; + debug_log(format!("{:?}", result)); +} diff --git a/src/mods/mod_tasks.rs b/src/mods/mod_tasks.rs new file mode 100644 index 0000000..827970f --- /dev/null +++ b/src/mods/mod_tasks.rs @@ -0,0 +1,206 @@ +use crate::mods::mod_debug::*; +use crate::mods::mod_i18n::*; +use crate::mods::mod_os::*; + +pub struct Rule { + /// Monitored service name + pub service: String, + /// Monitored URI + pub uri: String, + /// Monitored process name + pub process: String, + /// E-mail address for messages + pub email: String, + /// This command will be executed on state change + pub command: String, + /// Last state + pub last_state: bool, +} + +pub fn execute_web_task(task: &mut Rule, current_state:bool, just_started: bool) { + let locale = Locale::new(); + + if task.last_state != current_state || just_started { + if task.command.to_string() == "".to_string() { + if current_state { + println!("\u{2705} {} {}", task.uri, locale.t().state_changed_to_true.clone()); + } else { + println!("\u{274c} {} {}", task.uri, locale.t().state_changed_to_false.clone()); + } + } else { + if current_state { + debug_log( + format!( + "\u{2705} {} {}", + task.uri, + locale.t().state_changed_to_true.clone() + ) + ); + } else { + debug_log( + format!( + "\u{274c} {} {}", + task.uri, + locale.t().state_changed_to_false.clone() + ) + ); + } + + let subject: String = if current_state { + format!( + "\"\u{2705} {} {} ({}) {}\"", + locale.t().service, + task.service, + task.uri, + locale.t().is_online.clone() + ) + } else { + format!( + "\"\u{274c} {} {} ({}) {}\"", + locale.t().service, + task.service, + task.uri, + locale.t().is_offline.clone() + ) + }; + + let shell_cmd = + task.command.to_string() + .replace("", &task.email) + .replace("", &subject) + .replace("", &subject) + .replace("", &task.service) + .replace("", &task.uri) + .replace( + "", + if current_state { + "online" + } else { + "offline" + } + ); + + debug_log(format!("{} {}", locale.t().execute, shell_cmd)); + + execute(shell_cmd); + } + } + + if current_state { + debug_log( + format!( + "\u{2705} {} {}", + task.uri, + locale.t().check_is_ok.clone() + ) + ) + } else { + debug_log( + format!( + "\u{274c} {} {}", + task.uri, + locale.t().check_failed.clone() + ) + ); + } + + task.last_state = current_state; +} + +pub fn execute_os_task(task: &mut Rule, current_state:bool, just_started: bool) { + let locale = Locale::new(); + + if task.last_state != current_state || just_started { + if task.command.to_string() == "".to_string() { + if current_state { + println!( + "\u{2705} {} {}", + task.uri, + locale.t().state_changed_to_true.clone() + ); + } else { + println!( + "\u{274c} {} {}", + task.uri, + locale.t().state_changed_to_false.clone() + ) + } + } else { + if current_state { + debug_log( + format!( + "\u{2705} {} {}", + task.uri, + locale.t().state_changed_to_true.clone() + ) + ) + } else { + debug_log( + format!( + "\u{274c} {} {}", + task.uri, + locale.t().state_changed_to_false.clone() + ) + ) + } + + let subject: String = if current_state { + format!( + "\"\u{2705} {} {} ({}) {}\"", + locale.t().process, + task.service, + task.process, + locale.t().is_running.clone() + ) + } else { + format!( + "\"\u{274c} {} {} ({}) {}\"", + locale.t().process, + task.service, + task.process, + locale.t().is_not_running.clone() + ) + }; + + let shell_cmd = + task.command.to_string() + .replace("", &task.email) + .replace("", &subject) + .replace("", &subject) + .replace("", &task.service) + .replace("", &task.process) + .replace( + "", + if current_state { + "running" + } else { + "stopped" + } + ); + + debug_log(format!("{} {}", locale.t().execute, shell_cmd)); + + execute(shell_cmd); + } + } + + if current_state { + debug_log( + format!( + "\u{2705} {} {}", + task.process, + locale.t().is_running + ) + ); + } else { + debug_log( + format!( + "\u{274c} {} {}", + task.process, + locale.t().is_not_running + ) + ); + } + + task.last_state = current_state; +}