Compare commits
2 commits
ddab660945
...
82b944a748
Author | SHA1 | Date | |
---|---|---|---|
82b944a748 | |||
816a6daed1 |
5 changed files with 47 additions and 25 deletions
|
@ -35,7 +35,8 @@
|
|||
endpoints:[
|
||||
(label: "The code doesn't match!", endpoint: "http://example.com/", code: 204),
|
||||
(label: "The body doesn't match!", endpoint: "http://example.com/", body: "asdf"),
|
||||
(label: "Slow reponse time", endpoint: "http://slowwly.robertomurray.co.uk/delay/2000/url/"),
|
||||
(label: "Slow reponse time", endpoint: "http://slowwly.robertomurray.co.uk/delay/2000/url/", max_rtt: 1337),
|
||||
(label: "Plethora of issues!", endpoint: "http://slowwly.robertomurray.co.uk/delay/1000/url/", body: "asdf", code: 418, max_rtt: 50),
|
||||
(label: "Here's an error:", endpoint: "https://some-invalid-website.arpa")
|
||||
]
|
||||
),
|
||||
|
|
|
@ -9,6 +9,7 @@ pub struct EndpointConfig {
|
|||
pub body: Option<String>,
|
||||
pub body_hash: Option<String>,
|
||||
pub follow_redirects: Option<bool>,
|
||||
pub max_rtt: Option<i64>,
|
||||
pub should_err: Option<bool>,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{config::*, State};
|
||||
use crate::{config::*, updater::update_status, State};
|
||||
use actix_web::{
|
||||
error::ErrorInternalServerError, web::Data, Error as WebError, HttpResponse,
|
||||
Result as WebResult,
|
||||
|
@ -63,6 +63,34 @@ pub struct QueryResults {
|
|||
pub groups: Vec<StatusGroup>,
|
||||
}
|
||||
|
||||
impl QueryResults {
|
||||
pub fn new(config: Config) -> Self {
|
||||
let time = Utc::now();
|
||||
QueryResults {
|
||||
timestamp: time,
|
||||
timestamp_str: Self::format_timestamp(time),
|
||||
refresh_time: config.refresh_time,
|
||||
config: config.clone(),
|
||||
groups: update_status(&config),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, updated_groups: Vec<StatusGroup>) {
|
||||
self.update_timestamp();
|
||||
self.groups = updated_groups;
|
||||
}
|
||||
|
||||
fn update_timestamp(&mut self) {
|
||||
let current_time = Utc::now();
|
||||
self.timestamp = current_time;
|
||||
self.timestamp_str = Self::format_timestamp(current_time);
|
||||
}
|
||||
|
||||
fn format_timestamp(timestamp: DateTime<Utc>) -> String {
|
||||
timestamp.format("%Y-%m-%d %H:%M:%S").to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index(tmpl: Data<Tera>, state: Data<State>) -> WebResult<HttpResponse, WebError> {
|
||||
let state = state.read().unwrap();
|
||||
let mut ctx = Context::new();
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -19,7 +19,6 @@ mod updater;
|
|||
use self::{config::*, handlers::*, updater::*};
|
||||
use actix::System;
|
||||
use actix_web::{middleware::Logger, web::resource, App, HttpServer};
|
||||
use chrono::prelude::*;
|
||||
use ron::de::from_str;
|
||||
use std::{
|
||||
env::var,
|
||||
|
@ -35,24 +34,18 @@ use tokio::{
|
|||
pub type State = Arc<RwLock<QueryResults>>;
|
||||
|
||||
fn main() {
|
||||
System::run(move || {
|
||||
System::run(|| {
|
||||
let conf_file_loc =
|
||||
var("ENDSTAT_CONF").unwrap_or_else(|_| String::from("./config/endstat_conf.ron"));
|
||||
let config = from_str::<Config>(
|
||||
&read_to_string(&conf_file_loc).expect(&format!("finding {}", conf_file_loc)),
|
||||
)
|
||||
.unwrap();
|
||||
let bind_addr = config.bind_address.clone();
|
||||
let bind_addr = &config.bind_address;
|
||||
std::env::set_var("RUST_LOG", "actix_web=info");
|
||||
env_logger::init();
|
||||
|
||||
let state: State = Arc::new(RwLock::new(QueryResults {
|
||||
timestamp: Utc::now(),
|
||||
timestamp_str: Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||
refresh_time: config.refresh_time.clone(),
|
||||
config: config.clone(),
|
||||
groups: update_status(&config),
|
||||
}));
|
||||
let state = Arc::new(RwLock::new(QueryResults::new(config.clone())));
|
||||
|
||||
let clone_state = Arc::clone(&state);
|
||||
|
||||
|
|
|
@ -13,10 +13,8 @@ use std::time::Duration;
|
|||
|
||||
pub fn update_state(state: State) {
|
||||
let new_statuses = { Some(update_status(&state.read().unwrap().config)) };
|
||||
let mut write_state = state.try_write().expect("Could not unlock");
|
||||
write_state.timestamp = Utc::now();
|
||||
write_state.timestamp_str = Utc::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||
write_state.groups = new_statuses.unwrap();
|
||||
let mut state = state.try_write().expect("Could not unlock");
|
||||
state.update(new_statuses.unwrap());
|
||||
}
|
||||
|
||||
pub fn update_status(config: &Config) -> Vec<StatusGroup> {
|
||||
|
@ -70,7 +68,7 @@ fn get_result(
|
|||
error = append_err_msg(
|
||||
error,
|
||||
format!(
|
||||
"Status code mismatch: {} != {}.",
|
||||
"Status code mismatch: {} != {}",
|
||||
res.status().as_u16(),
|
||||
code
|
||||
),
|
||||
|
@ -86,12 +84,17 @@ fn get_result(
|
|||
} else if !body.is_empty() && res_body != body {
|
||||
error = append_err_msg(
|
||||
error,
|
||||
format!("Body mismatch: {} != {}.", res_body.len(), body.len()),
|
||||
format!("Body mismatch: {} != {}", res_body.len(), body.len()),
|
||||
);
|
||||
}
|
||||
|
||||
if rtt.num_seconds() >= 2 {
|
||||
error = append_err_msg(error, format!("RTT too long: {}", rtt_string));
|
||||
if let Some(max_rtt) = endpoint.max_rtt {
|
||||
if rtt.num_milliseconds() > max_rtt {
|
||||
error = append_err_msg(
|
||||
error,
|
||||
format!("RTT too long: {} > {}s", rtt_string, max_rtt as f64 / 1000.),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if error.is_some() {
|
||||
|
@ -123,12 +126,8 @@ fn get_url(base: &Option<String>, path: &String, port: Option<u16>) -> Result<St
|
|||
}
|
||||
|
||||
fn append_err_msg(optional: Option<String>, to_append: String) -> Option<String> {
|
||||
// Turns out Rust doesn't recognize that only one of the FnOnce occurs, so
|
||||
// as a result both closures want ownership of to_append
|
||||
// Some(optional.map_or_else(|| to_append, |msg| format!("{} {}", msg, to_append)))
|
||||
|
||||
Some(match optional {
|
||||
Some(e) => format!("{} {}", e, to_append),
|
||||
Some(e) => format!("{}\n{}", e, to_append),
|
||||
None => to_append,
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue