From 0d14ab250971c360f9be5097768c50aec5f58b5a Mon Sep 17 00:00:00 2001 From: prplV Date: Wed, 17 Jul 2024 13:47:11 +0300 Subject: [PATCH] logs + restarting prc fix --- Cargo.lock | 298 +++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 5 +- settings.json | 3 +- src/main.rs | 83 ++++++++++---- 4 files changed, 361 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af8a9e3..32a1931 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,79 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -50,6 +123,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytes" version = "1.6.0" @@ -68,6 +147,55 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.5", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -86,6 +214,35 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "inotify" version = "0.10.2" @@ -108,12 +265,27 @@ dependencies = [ "libc", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.155" @@ -130,6 +302,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + [[package]] name = "memchr" version = "2.7.4" @@ -156,6 +334,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -175,6 +362,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "parking_lot" version = "0.12.3" @@ -232,10 +425,42 @@ dependencies = [ ] [[package]] -name = "runner-rs" -version = "0.4.0" +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "runner-rs" +version = "0.4.2" +dependencies = [ + "chrono", + "env_logger", "inotify", + "log", "serde", "serde_json", "tokio", @@ -362,12 +587,81 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index e36d383..c86f3af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,13 @@ [package] name = "runner-rs" -version = "0.4.0" +version = "0.4.2" edition = "2021" [dependencies] +chrono = "0.4.38" +env_logger = "0.11.3" inotify = "0.10.2" +log = "0.4.22" serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.118" tokio = { version = "1.38.0", features = ["full", "time"] } diff --git a/settings.json b/settings.json index 24f32aa..dfb86c6 100644 --- a/settings.json +++ b/settings.json @@ -1,4 +1,5 @@ { + "id" : 1, "processes" : [{ "name" : "web-server", "path" : "/home/vladislav/web/web-server", @@ -17,7 +18,7 @@ "src" : "/home/vladislav/web/", "triggers" : { "onDelete" : "stop", - "onChange" : "hold" + "onChange" : "restart" } } ], diff --git a/src/main.rs b/src/main.rs index fb3a26b..62a40be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,25 @@ +// json parsing use serde::{ Deserialize, Serialize }; use serde_json; +// async multi-threaded execution +use tokio::time::{ Duration, Instant }; +use tokio::sync::mpsc; use tokio::join; +// fatal errors handler use core::panic; +// utils use std::fmt::Debug; use std::fs; use std::path::Path; use std::process::{ Command, Output }; -use std::sync::{ Arc, Mutex }; -use tokio::time::{ Duration, Instant }; -use tokio::sync::mpsc; +use std::sync::Arc; +// file change handler use inotify::{ Inotify, WatchMask }; +// logging +use std::io::Write; +use chrono::Local; +use env_logger::Builder; +use log::{error, max_level, warn, LevelFilter}; /// # an Error enum (nextly will be deleted and replaced) enum CustomError { @@ -20,6 +30,8 @@ enum CustomError { /// > (needed in serialization and deserialization) #[derive(Debug, Serialize, Deserialize, Clone)] struct Processes { + #[serde(rename="id")] + runner_id: usize, #[serde(default)] processes : Vec, } @@ -83,21 +95,43 @@ struct FIleTriggers { #[tokio::main(flavor = "multi_thread")] async fn main() { + + Builder::new() + .format(|buf, record|{ + writeln!(buf, + "{} [{}] - {}", + Local::now().format("%d-%m-%Y %H:%M:%S"), + record.level(), + record.args(), + ) + }) + .filter(None, LevelFilter::Info) + .init(); + let processes = load_processes("settings.json"); // let mut error_counter = 0; if processes.processes.len() == 0 { - eprintln!("Error: Processes list is null, runner-rs initialization is stopped"); + error!("Processes list is null, runner-rs initialization is stopped"); + // eprintln!("Error: Processes list is null, runner-rs initialization is stopped"); return; } let mut handler: Vec> = vec![]; for proc in processes.processes.iter() { - println!("Process '{}' on stage:\n{}\nDepends on {} file(s), {} service(s)\n", + log::info!("Process '{}' on stage: {}. Depends on {} file(s), {} service(s)", proc.name, proc.path, proc.dependencies.files.len(), - proc.dependencies.services.len()); + proc.dependencies.services.len() + ); + + // println!("Process '{}' on stage:\n{}\nDepends on {} file(s), {} service(s)\n", + // proc.name, + // proc.path, + // proc.dependencies.files.len(), + // proc.dependencies.services.len() + // ); // creating msg channel // can or should be executed in new thread @@ -154,7 +188,7 @@ async fn run_daemons( // 1 - File-dependency handling error -> terminating (after waiting) 1 => { if is_active(&proc.name).await { - println!("Dependency handling error: Terminating {} process ..." , &proc.name); + error!("Dependency handling error: Terminating {} process ..." , &proc.name); terminate_process(&proc.name).await; tokio::time::sleep(Duration::from_millis(100)).await; } @@ -163,23 +197,23 @@ async fn run_daemons( // 2 - File-dependency handling error -> holding (after waiting) 2 => { if !is_frozen(&proc.name).await { - println!("Dependency handling error: Freezing {} process ..." , &proc.name); + error!("Dependency handling error: Freezing {} process ..." , &proc.name); freeze_process(&proc.name).await; tokio::time::sleep(Duration::from_millis(100)).await; } }, // 3 - Running process error 3 => { - println!("Error due to starting {} process", &proc.name); + error!("Error due to starting {} process", &proc.name); }, // 4 - Timeout of waiting service-dependency -> staying (after waiting) 4 => { - println!("Timeout of waiting service-dependency: Ignoring on {} process ..." , &proc.name); + warn!("Timeout of waiting service-dependency: Ignoring on {} process ..." , &proc.name); }, // 5 - Timeout of waiting service-dependency -> terminating (after waiting) 5 => { if is_active(&proc.name).await { - println!("Timeout of waiting service-dependency: Terminating {} process ..." , &proc.name); + error!("Timeout of waiting service-dependency: Terminating {} process ..." , &proc.name); terminate_process(&proc.name).await; tokio::time::sleep(Duration::from_millis(100)).await; } @@ -188,45 +222,45 @@ async fn run_daemons( // 6 - Timeout of waiting service-dependency -> holding (after waiting) 6 => { if !is_frozen(&proc.name).await { - println!("Timeout of waiting service-dependency: Freezing {} process ..." , &proc.name); + error!("Timeout of waiting service-dependency: Freezing {} process ..." , &proc.name); freeze_process(&proc.name).await; tokio::time::sleep(Duration::from_millis(100)).await; } }, // // 7 - File-dependency change -> terminating (after check) 7 => { - println!("File-dependency warning (file changed). Terminating {} process...", &proc.name); + error!("File-dependency warning (file changed). Terminating {} process...", &proc.name); terminate_process(&proc.name).await; tokio::time::sleep(Duration::from_millis(100)).await; }, // // 8 - File-dependency change -> restarting (after check) 8 => { - println!("File-dependency warning (file changed). Restarting {} process...", &proc.name); + warn!("File-dependency warning (file changed). Restarting {} process...", &proc.name); let _ = restart_process(&proc.name, &proc.path).await; tokio::time::sleep(Duration::from_millis(100)).await; }, // // 9 - File-dependency change -> staying (after check) 9 => { - println!("File-dependency warning (file changed). Ignoring on {} process...", &proc.name); + warn!("File-dependency warning (file changed). Ignoring on {} process...", &proc.name); }, // 10 - Process unfreaze call via file handler 10 => { if is_frozen(&proc.name).await { - println!("Unfreezing process {} call...", &proc.name); + warn!("Unfreezing process {} call...", &proc.name); unfreeze_process(&proc.name).await; } }, // 11 - Process unfreaze call via service handler 11 => { if is_frozen(&proc.name).await { - println!("Unfreezing process {} call...", &proc.name); + warn!("Unfreezing process {} call...", &proc.name); unfreeze_process(&proc.name).await; } }, // 101 - Impermissible trigger values in JSON 101 => { - println!("Impermissible trigger values in JSON"); + error!("Impermissible trigger values in JSON"); if is_active(&proc.name).await { terminate_process(&proc.name).await; } @@ -308,6 +342,7 @@ async fn unfreeze_process(name: &str) { } async fn restart_process(name: &str, path: &str) -> Result<(), CustomError> { terminate_process(name).await; + tokio::time::sleep(Duration::from_millis(100)).await; return start_process(name, path).await; } @@ -318,7 +353,7 @@ async fn start_process(name: &str, path: &str) -> Result<(), CustomError> { match command.spawn() { Ok(_) => { - println!("Process {} is running now!", name); + warn!("Process {} is running now!", name); Ok(()) }, Err(_) => { @@ -447,7 +482,7 @@ async fn service_handler(name: &str, services: &Vec, tx: Arc { }, @@ -488,10 +523,10 @@ async fn looped_service_connecting( if serv.triggers.wait == 0 { loop { tokio::time::sleep(Duration::from_secs(serv.triggers.delay.into())).await; - println!("Attempting to connect from {} process to {}:{}",&name, &serv.hostname, &serv.port ); + warn!("Attempting to connect from {} process to {}:{}",&name, &serv.hostname, &serv.port ); match check_service(&serv.hostname, &serv.port).await { Ok(_) => { - println!("Successfully connected to {} from {} process!", &serv.hostname, &name); + log::info!("Successfully connected to {} from {} process!", &serv.hostname, &name); break; }, Err(_) => { @@ -504,10 +539,10 @@ async fn looped_service_connecting( let start = Instant::now(); while start.elapsed().as_secs() < serv.triggers.wait.into() { tokio::time::sleep(Duration::from_secs(serv.triggers.delay.into())).await; - println!("Attempting to connect from {} process to {}:{}",&name, &serv.hostname, &serv.port ); + warn!("Attempting to connect from {} process to {}:{}",&name, &serv.hostname, &serv.port ); match check_service(&serv.hostname, &serv.port).await { Ok(_) => { - println!("SUCCESS!"); + log::info!("Successfully connected to {} from {} process!", &serv.hostname, &name); return Ok(()); }, Err(_) => {