now can run

This commit is contained in:
2020-05-05 00:50:14 +08:00
parent fd83169ba4
commit 237037e169
4 changed files with 250 additions and 18 deletions

View File

@@ -1,9 +1,23 @@
use std::process::Command;
use std::{
fs,
panic,
thread,
time::Duration,
process::Command,
sync::Arc,
};
use chrono::prelude::*;
use serde::{ Deserialize, Serialize, };
use rust_util::util_msg::{ print_info, print_error, };
use rust_util::{
util_file::locate_file,
util_msg::{ print_info, print_error, print_debug, }
};
use dingtalk::DingTalk;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct KeepRunningConfig {
check_inverval_secs: Option<u64>,
show_debug_output: Option<bool>,
notify_token: String,
items: Vec<KeepRunningConfigItem>,
}
@@ -15,18 +29,91 @@ struct KeepRunningConfigItem {
}
fn main() {
print_info("Start run: ps aux");
let output_str = match ps_aux() {
Some(output_str) => output_str, None => return,
};
let lines = read_str_to_lines(&output_str);
panic::set_hook(Box::new(|panic_info| {
print_error(&format!("Panic in running keeprunningd: {:?}", panic_info));
}));
// println!("{}", output_str);
// for ln in &lines {
// println!(">>>>>>> {}", ln);
// }
println!("{:?}", lines.iter().filter(|ln| ln.contains("java") && ln.contains("aaa")).collect::<Vec<_>>());
println!("{}", lines.len());
let config_file_opt = locate_file(&[
"keeprunningd.json".into(),
"~/keeprunningd.json".into(),
"/etc/keeprunningd.json".into()
]);
let config_file = match config_file_opt {
None => {
print_error("Cannot find config file!");
return;
},
Some(config_file) => {
print_info(&format!("Find config file: {:?}", &config_file));
config_file
},
};
let config_file_content = match fs::read_to_string(&config_file) {
Ok(c) => c, Err(err) => {
print_error(&format!("Read config file {:?}, error: {}", &config_file, err));
return;
},
};
let keep_running_config: KeepRunningConfig = match serde_json::from_str(&config_file_content) {
Ok(c) => c, Err(err) => {
print_error(&format!("Parse config file: {:?}, error: {}", &config_file, err));
return;
},
};
if keep_running_config.show_debug_output.unwrap_or(false) {
if let Ok(json) = serde_json::to_string_pretty(&keep_running_config) {
print_debug(&format!("Config: {}", json));
}
}
let keep_running_config: Arc<KeepRunningConfig> = Arc::new(keep_running_config);
for check_cnt in 0.. {
print_info(&format!("Check index: {} @{:?}", check_cnt, Local::now()));
keep_runningd(keep_running_config.clone());
thread::sleep(Duration::from_secs(keep_running_config.check_inverval_secs.unwrap_or(60 * 60)));
}
}
fn keep_runningd(keep_running_config: Arc<KeepRunningConfig>) {
let t = thread::spawn(move || {
let ps_aux_lines = read_str_to_lines(&match ps_aux() { Some(p) => p, None => return, });
for keep_running_config_item in &keep_running_config.items {
let check_lines = ps_aux_lines.iter().filter(|ln| {
keep_running_config_item.grep_tokens.iter().all(|t| ln.contains(t))
}).collect::<Vec<_>>();
if check_lines.is_empty() { // if check fail!
print_info("Send DingTalk notification!");
use tokio::runtime;
match runtime::Builder::new().basic_scheduler().enable_all().build() {
Err(err) => print_error(&format!("Prepare tokio runtime error: {}", err)),
Ok(mut rt) => {
let mut sb = String::with_capacity(1024);
sb.push_str(&format!("Check failed: {}", &keep_running_config_item.title));
sb.push_str(&format!("\ncheck time: {:?}", Local::now()));
rt.block_on(send_notify(&keep_running_config.notify_token, &sb));
},
}
} else if keep_running_config.show_debug_output.unwrap_or(false) {
print_debug(&format!("Find: {:?}", &check_lines));
}
}
});
if let Err(err) = t.join() {
print_error(&format!("Join check thread error: {:?}", err));
}
}
async fn send_notify(notify_token: &str, text: &str) {
match DingTalk::from_token(&notify_token) {
Err(err) => print_error(&format!("Prepare DingTalk error: {}", err)),
Ok(dt) => if let Err(err) = dt.send_text(text).await {
print_error(&format!("Send DingTalk message error: {}", err));
},
}
}
fn ps_aux() -> Option<String> {
@@ -39,16 +126,17 @@ fn ps_aux() -> Option<String> {
},
};
match String::from_utf8(output.stdout) {
Ok(output_str) => Some(output_str), Err(err) => {
Ok(output_str) => Some(output_str),
Err(err) => {
print_error(&format!("Get ps output as utf8 error: {}", err));
return None;
None
},
}
}
/// Split string to lines, splited by '\r', '\n' or "\r\n"
fn read_str_to_lines(s: &str) -> Vec<String> {
let mut r = vec![];
let mut line = String::new();
let mut cs = s.chars();
while let Some(c) = cs.next() {
@@ -64,6 +152,8 @@ fn read_str_to_lines(s: &str) -> Vec<String> {
} else {
line.push(nc);
}
} else {
break;
}
}
} else {