user controlled timeout for net monitor

This commit is contained in:
Christoph J. Scherr 2023-07-10 21:54:28 +02:00
parent 7b2e431bb9
commit 8dc4a0aade
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
5 changed files with 25 additions and 14 deletions

View File

@ -21,10 +21,12 @@ class UptimeStatus:
success_ratio_target: int success_ratio_target: int
""" the number of reachable [`urls`](UptimeStatus::urls) """ """ the number of reachable [`urls`](UptimeStatus::urls) """
reachable: int reachable: int
""" set a timeout (in ms) """
timeout: int
"""URL list cant be ported to python, use UptimeStatus.urls()""" """URL list cant be ported to python, use UptimeStatus.urls()"""
__urls: ... __urls: ...
def __init__(self, success_ratio_target: int, url_strs: list[str]) -> None: def __init__(self, success_ratio_target: int, url_strs: list[str], timeout: int) -> None:
""" """
create a new UptimeStatus and check it create a new UptimeStatus and check it
@ -71,7 +73,7 @@ class UptimeStatus:
""" """
... ...
def continuous_uptime_monitor(success_ratio_target: int, urls: list[str], interval: int) -> None: def continuous_uptime_monitor(success_ratio_target: int, urls: list[str], interval: int, timeout: int) -> None:
""" """
Uptime monitor Uptime monitor

View File

@ -99,7 +99,11 @@ pub enum NetCommands {
/// Don't check for default URLs /// Don't check for default URLs
#[clap(short, long)] #[clap(short, long)]
no_default: bool no_default: bool,
/// set a timeout (in ms)
#[clap(short, long, default_value_t = 100)]
timeout: u64
}, },
/// discover hosts in your network /// discover hosts in your network

View File

@ -75,7 +75,8 @@ pub fn net(cli: &Cli, command: NetCommands) {
repeat, repeat,
success_ratio, success_ratio,
extra_urls, extra_urls,
no_default no_default,
timeout
} => { } => {
let urls: Vec<String>; let urls: Vec<String>;
if no_default { if no_default {
@ -91,9 +92,9 @@ pub fn net(cli: &Cli, command: NetCommands) {
} }
let _verbose = cli.verbose.log_level().is_some(); let _verbose = cli.verbose.log_level().is_some();
if repeat > 0 { if repeat > 0 {
uptime::continuous_uptime_monitor(success_ratio, urls, repeat * 1000); uptime::continuous_uptime_monitor(success_ratio, urls, repeat * 1000, timeout);
} else { } else {
let status = uptime::UptimeStatus::new(success_ratio, &urls); let status = uptime::UptimeStatus::new(success_ratio, &urls, timeout);
println!("{}", status); println!("{}", status);
} }
} }

View File

@ -22,7 +22,7 @@ pub mod monitoring;
//// CONSTANTS ///////////////////////////////////////////////////////////////////////////////////// //// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
/// how long to wait for a remove server to respond in ms /// how long to wait for a remove server to respond in ms
pub const REQUEST_TIMEOUT: u64 = 2000; pub const DEFAULT_REQUEST_TIMEOUT: u64 = 2000;
//// STATICS /////////////////////////////////////////////////////////////////////////////////////// //// STATICS ///////////////////////////////////////////////////////////////////////////////////////

View File

@ -62,13 +62,15 @@ pub struct UptimeStatus {
pub reachable: usize, pub reachable: usize,
/// which urls to check in [`check()`](UptimeStatus::check) /// which urls to check in [`check()`](UptimeStatus::check)
pub urls: Vec<Url>, pub urls: Vec<Url>,
/// timeout length for requests (in ms)
pub timeout: u64
} }
//// IMPLEMENTATION //////////////////////////////////////////////////////////////////////////////// //// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
/// Main implementation /// Main implementation
impl UptimeStatus { impl UptimeStatus {
/// ## create a new `UptimeStatus` and perform it's check /// ## create a new `UptimeStatus` and perform it's check
pub fn new(success_ratio_target: u8, url_strs: &Vec<String>) -> Self { pub fn new(success_ratio_target: u8, url_strs: &Vec<String>, timeout: u64) -> Self {
assert!(success_ratio_target <= 100); assert!(success_ratio_target <= 100);
let mut status = UptimeStatus { let mut status = UptimeStatus {
success: false, success: false,
@ -76,6 +78,7 @@ impl UptimeStatus {
success_ratio_target, success_ratio_target,
reachable: 0, reachable: 0,
urls: Vec::new(), urls: Vec::new(),
timeout
}; };
for s in url_strs { for s in url_strs {
let url = reqwest::Url::from_str(&s); let url = reqwest::Url::from_str(&s);
@ -102,7 +105,7 @@ impl UptimeStatus {
self.reachable = 0; self.reachable = 0;
self.urls.iter().for_each(|url| { self.urls.iter().for_each(|url| {
let client = reqwest::blocking::Client::builder() let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_millis(crate::networking::REQUEST_TIMEOUT)) .timeout(Duration::from_millis(self.timeout))
.build() .build()
.expect("could not build a client for https requests"); .expect("could not build a client for https requests");
let response = client.get(url.clone()).send(); let response = client.get(url.clone()).send();
@ -149,8 +152,8 @@ impl UptimeStatus {
impl UptimeStatus { impl UptimeStatus {
/// calls [`new()`](UptimeStatus::new) with python compatible arguments /// calls [`new()`](UptimeStatus::new) with python compatible arguments
#[new] #[new]
pub fn py_new(success_ratio_target: u8, url_strs: Vec<String>) -> Self { pub fn py_new(success_ratio_target: u8, url_strs: Vec<String>, timeout: u64) -> Self {
Self::new(success_ratio_target, &url_strs) Self::new(success_ratio_target, &url_strs, timeout)
} }
/// Same as [`check()`](UptimeStatus::check) /// Same as [`check()`](UptimeStatus::check)
@ -237,7 +240,7 @@ impl fmt::Display for UptimeStatus {
/// On change of status, an update will be logged at [INFO Level](log::Level::Info), containing /// On change of status, an update will be logged at [INFO Level](log::Level::Info), containing
/// information on your current status, including timestamps of the last up/down time and durations /// information on your current status, including timestamps of the last up/down time and durations
/// since. /// since.
pub fn continuous_uptime_monitor(success_ratio_target: u8, urls: Vec<String>, interval: u64) { pub fn continuous_uptime_monitor(success_ratio_target: u8, urls: Vec<String>, interval: u64, timeout: u64) {
if urls.len() == 0 { if urls.len() == 0 {
error!("No URLs provided. There is nothing to monitor."); error!("No URLs provided. There is nothing to monitor.");
return; return;
@ -246,7 +249,7 @@ pub fn continuous_uptime_monitor(success_ratio_target: u8, urls: Vec<String>, in
let interval = std::time::Duration::from_millis(interval); let interval = std::time::Duration::from_millis(interval);
let mut last_downtime: Option<SystemTime> = None; let mut last_downtime: Option<SystemTime> = None;
let mut last_uptime: Option<SystemTime> = None; let mut last_uptime: Option<SystemTime> = None;
let mut status = UptimeStatus::new(success_ratio_target, &urls); let mut status = UptimeStatus::new(success_ratio_target, &urls, timeout);
let mut last_was_up: bool = false; let mut last_was_up: bool = false;
let mut last_ratio: u8 = status.success_ratio; let mut last_ratio: u8 = status.success_ratio;
loop { loop {
@ -292,10 +295,11 @@ pub fn py_continuous_uptime_monitor(
success_ratio_target: u8, success_ratio_target: u8,
urls: Vec<String>, urls: Vec<String>,
interval: u64, interval: u64,
timeout: u64
) -> PyResult<()>{ ) -> PyResult<()>{
// execute the function in a different thread // execute the function in a different thread
let _th = std::thread::spawn(move || { let _th = std::thread::spawn(move || {
continuous_uptime_monitor(success_ratio_target, urls, interval); continuous_uptime_monitor(success_ratio_target, urls, interval, timeout);
}); });
loop { loop {
Python::check_signals(py)?; Python::check_signals(py)?;