Use atomics instead of mutexes

Use atomics instead of mutexes to improve access on metrics. Therefor
also remove unneeded borrows.
This commit is contained in:
finga 2021-11-13 14:35:40 +01:00
parent b4b46ebd58
commit a122bf28d2
2 changed files with 38 additions and 57 deletions

View file

@ -29,7 +29,7 @@ use std::{
fs::File,
io::BufReader,
net::{IpAddr, Ipv4Addr, SocketAddr},
sync::Mutex,
sync::atomic::{AtomicUsize, Ordering},
};
mod cli;
@ -42,15 +42,15 @@ use crate::{
#[derive(Debug, Default)]
struct WebhookeyMetrics {
requests_received: Mutex<usize>,
requests_invalid: Mutex<usize>,
hooks_successful: Mutex<usize>,
hooks_forbidden: Mutex<usize>,
hooks_unmatched: Mutex<usize>,
commands_executed: Mutex<usize>,
commands_execution_failed: Mutex<usize>,
commands_successful: Mutex<usize>,
commands_failed: Mutex<usize>,
requests_received: AtomicUsize,
requests_invalid: AtomicUsize,
hooks_successful: AtomicUsize,
hooks_forbidden: AtomicUsize,
hooks_unmatched: AtomicUsize,
commands_executed: AtomicUsize,
commands_execution_failed: AtomicUsize,
commands_successful: AtomicUsize,
commands_failed: AtomicUsize,
}
#[derive(Debug, Deserialize, Serialize)]
@ -304,15 +304,15 @@ webhookey_commands_successful {}
# TYPE webhookey_commands_failed gauge
webhookey_commands_failed {}
",
metrics.requests_received.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.requests_invalid.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.hooks_successful.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.hooks_forbidden.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.hooks_unmatched.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.commands_executed.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.commands_execution_failed.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.commands_successful.lock().unwrap(), // TODO: Check if unwrap need to be fixed
metrics.commands_failed.lock().unwrap() // TODO: Check if unwrap need to be fixed
metrics.requests_received.load(Ordering::Relaxed),
metrics.requests_invalid.load(Ordering::Relaxed),
metrics.hooks_successful.load(Ordering::Relaxed),
metrics.hooks_forbidden.load(Ordering::Relaxed),
metrics.hooks_unmatched.load(Ordering::Relaxed),
metrics.commands_executed.load(Ordering::Relaxed),
metrics.commands_execution_failed.load(Ordering::Relaxed),
metrics.commands_successful.load(Ordering::Relaxed),
metrics.commands_failed.load(Ordering::Relaxed),
)
}
@ -325,15 +325,12 @@ impl<'r> FromData<'r> for Hooks {
data: Data<'r>,
) -> Outcome<Self, (Status, Self::Error), Data<'r>> {
{
let requests_received = &mut request
request
.guard::<&State<WebhookeyMetrics>>()
.await
.unwrap() // TODO: Check if unwrap need to be fixed
.requests_received
.lock()
.unwrap(); // TODO: Check if unwrap need to be fixed
**requests_received += 1;
.fetch_add(1, Ordering::Relaxed);
}
match Hooks::get_commands(request, data).await {
@ -343,15 +340,12 @@ impl<'r> FromData<'r> for Hooks {
.client_ip()
.unwrap_or(IpAddr::V4(Ipv4Addr::UNSPECIFIED));
let hooks_unmatched = &mut request
request
.guard::<&State<WebhookeyMetrics>>()
.await
.unwrap() // TODO: Check if unwrap need to be fixed
.hooks_unmatched
.lock()
.unwrap(); // TODO: Check if unwrap need to be fixed
**hooks_unmatched += 1;
.fetch_add(1, Ordering::Relaxed);
warn!("Unmatched hook from {}", &client_ip);
return Failure((Status::NotFound, WebhookeyError::UnmatchedHook(*client_ip)));
@ -362,30 +356,24 @@ impl<'r> FromData<'r> for Hooks {
Err(WebhookeyError::Unauthorized(e)) => {
error!("{}", WebhookeyError::Unauthorized(e));
let hooks_forbidden = &mut request
request
.guard::<&State<WebhookeyMetrics>>()
.await
.unwrap() // TODO: Check if unwrap need to be fixed
.hooks_forbidden
.lock()
.unwrap(); // TODO: Check if unwrap need to be fixed
**hooks_forbidden += 1;
.fetch_add(1, Ordering::Relaxed);
Failure((Status::Unauthorized, WebhookeyError::Unauthorized(e)))
}
Err(e) => {
error!("{}", e);
let requests_invalid = &mut request
request
.guard::<&State<WebhookeyMetrics>>()
.await
.unwrap() // TODO: Check if unwrap need to be fixed
.requests_invalid
.lock()
.unwrap(); // TODO: Check if unwrap need to be fixed
**requests_invalid += 1;
.fetch_add(1, Ordering::Relaxed);
Failure((Status::BadRequest, e))
}
@ -410,26 +398,19 @@ async fn receive_hook<'a>(
trace!("Output of command `{}` on stdout: {:?}", &command, &stdout);
debug!("Output of command `{}` on stderr: {:?}", &command, &stderr);
let commands_executed = &mut metrics.commands_executed.lock().unwrap(); // TODO: Check if unwrap need to be fixed
**commands_executed += 1;
metrics.commands_executed.fetch_add(1, Ordering::Relaxed);
match status {
0 => {
let commands_successful = &mut metrics.commands_successful.lock().unwrap(); // TODO: Check if unwrap need to be fixed
**commands_successful += 1;
}
_ => {
let commands_failed = &mut metrics.commands_failed.lock().unwrap(); // TODO: Check if unwrap need to be fixed
**commands_failed += 1;
}
}
let _ = match status {
0 => metrics.commands_successful.fetch_add(1, Ordering::Relaxed),
_ => metrics.commands_failed.fetch_add(1, Ordering::Relaxed),
};
}
Err(e) => {
error!("Execution of `{}` failed: {}", &command, e);
let command_execution_failed =
&mut metrics.commands_execution_failed.lock().unwrap(); // TODO: Check if unwrap need to be fixed
**command_execution_failed += 1;
metrics
.commands_execution_failed
.fetch_add(1, Ordering::Relaxed);
}
}
});
@ -446,10 +427,10 @@ async fn metrics(
if let Some(metrics_config) = &config.metrics {
if let Some(filter) = &metrics_config.ip_filter {
if filter.validate(&address.ip()) {
return Some(get_metrics(&metrics));
return Some(get_metrics(metrics));
}
} else {
return Some(get_metrics(&metrics));
return Some(get_metrics(metrics));
}
}

View file

@ -74,7 +74,7 @@ impl JsonFilter {
let regex = Regex::new(&self.regex).map_err(WebhookeyError::Regex)?;
if let Some(value) = data.pointer(&self.pointer) {
if regex.is_match(&self.get_string(&value)?) {
if regex.is_match(&self.get_string(value)?) {
debug!("Regex `{}` for `{}` matches", &self.regex, &self.pointer);
return Ok(true);