|
|
|
@ -18,8 +18,10 @@
|
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
|
|
|
********************************************************************************/
|
|
|
|
|
use crate::config::Config;
|
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
use async_anyhow_logger::catch;
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
use log::{error, info, trace};
|
|
|
|
|
use log::{info, trace};
|
|
|
|
|
use prometheus::*;
|
|
|
|
|
use std::net::IpAddr;
|
|
|
|
|
use std::time::Duration;
|
|
|
|
@ -39,41 +41,33 @@ lazy_static! {
|
|
|
|
|
.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) async fn start_pinging_hosts(
|
|
|
|
|
config: Config,
|
|
|
|
|
) -> std::result::Result<(), tokio_ping::Error> {
|
|
|
|
|
let pinger = match Pinger::new().await {
|
|
|
|
|
Ok(pinger) => pinger,
|
|
|
|
|
Err(error) => {
|
|
|
|
|
error!("Couldn't create pinger: {}", error);
|
|
|
|
|
std::process::exit(1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
pub(crate) async fn start_pinging_hosts(config: Config) -> Result<()> {
|
|
|
|
|
let pinger = Pinger::new().await.context("Couldn't create pinger")?;
|
|
|
|
|
let mut handles = vec![];
|
|
|
|
|
for (host, interval) in config.hosts.clone() {
|
|
|
|
|
info!("Spawn ping task for {}", host);
|
|
|
|
|
tokio::spawn(ping_host(pinger.clone(), host, interval));
|
|
|
|
|
handles.push(tokio::spawn(catch(ping_host(pinger.clone(), host, interval))));
|
|
|
|
|
}
|
|
|
|
|
let (result, _, _) = futures::future::select_all(handles).await;
|
|
|
|
|
result?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn ping_host(pinger: Pinger, host: IpAddr, interval: u64) {
|
|
|
|
|
async fn ping_host(pinger: Pinger, host: IpAddr, interval: u64) -> Result<()> {
|
|
|
|
|
let mut pingchain = pinger.chain(host).timeout(Duration::from_secs(3));
|
|
|
|
|
let mut interval = tokio::time::interval(Duration::from_millis(interval));
|
|
|
|
|
let host_string = host.to_string();
|
|
|
|
|
loop {
|
|
|
|
|
interval.tick().await;
|
|
|
|
|
tokio::spawn(handle_ping_result(pingchain.send(), host_string.clone()));
|
|
|
|
|
tokio::spawn(catch(handle_ping_result(
|
|
|
|
|
pingchain.send(),
|
|
|
|
|
host_string.clone(),
|
|
|
|
|
)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn handle_ping_result(result: PingFuture, host: String) {
|
|
|
|
|
let pong = match result.await {
|
|
|
|
|
Ok(pong) => pong,
|
|
|
|
|
Err(error) => {
|
|
|
|
|
error!("Couldn't ping {}: {}", &host, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
async fn handle_ping_result(result: PingFuture, host: String) -> Result<()> {
|
|
|
|
|
let pong = result.await.context(format!("Couldn't ping {}", &host))?;
|
|
|
|
|
match pong {
|
|
|
|
|
Some(time) => {
|
|
|
|
|
let ms = time.as_millis();
|
|
|
|
@ -87,4 +81,6 @@ async fn handle_ping_result(result: PingFuture, host: String) {
|
|
|
|
|
PING_HISTOGRAM.with_label_values(&[&host]).observe(3000.0);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|