use crate::Config; use log::warn; use rocket::{get, State}; use std::{ net::SocketAddr, sync::atomic::{AtomicUsize, Ordering}, }; #[derive(Debug, Default)] pub struct Metrics { pub requests_received: AtomicUsize, pub requests_invalid: AtomicUsize, pub hooks_successful: AtomicUsize, pub hooks_forbidden: AtomicUsize, pub hooks_unmatched: AtomicUsize, pub commands_executed: AtomicUsize, pub commands_execution_failed: AtomicUsize, pub commands_successful: AtomicUsize, pub commands_failed: AtomicUsize, } #[get("/metrics")] pub async fn metrics( address: SocketAddr, metrics: &State, config: &State, ) -> Option { // Are metrics configured? if let Some(metrics_config) = &config.metrics { // Are metrics enabled? if metrics_config.enabled { // Is a filter configured? if let Some(filter) = &metrics_config.ip_filter { // Does the request match the filter? if filter.validate(&address.ip()) { return Some(metrics.get_metrics()); } } else { return Some(metrics.get_metrics()); } } } warn!("Forbidden request for metrics: {:?}", address); None } impl Metrics { fn get_metrics(&self) -> String { format!( r"# HELP webhookey_requests_received Number of requests received # TYPE webhookey_requests_received gauge webhookey_requests_received {} # HELP webhookey_requests_invalid Number of invalid requests received # TYPE webhookey_requests_invalid gauge webhookey_requests_invalid {} # HELP webhookey_hooks_successful Number of successfully executed hooks # TYPE webhookey_hooks_successful gauge webhookey_hooks_sucessful {} # HELP webhookey_hooks_forbidden Number of forbidden requests # TYPE webhookey_hooks_forbidden gauge webhookey_hooks_forbidden {} # HELP webhookey_hooks_unmatched Number of unmatched requests # TYPE webhookey_hooks_unmatched gauge webhookey_hooks_unmatched {} # HELP webhookey_commands_executed Number of commands executed # TYPE webhookey_commands_executed gauge webhookey_commands_executed {} # HELP webhookey_commands_execution_failed Number of commands failed to execute # TYPE webhookey_commands_execution_failed gauge webhookey_commands_execution_failed {} # HELP webhookey_commands_successful Number of executed commands returning return code 0 # TYPE webhookey_commands_successful gauge webhookey_commands_successful {} # HELP webhookey_commands_failed Number of executed commands returning different return code than 0 # TYPE webhookey_commands_failed gauge webhookey_commands_failed {} ", self.requests_received.load(Ordering::Relaxed), self.requests_invalid.load(Ordering::Relaxed), self.hooks_successful.load(Ordering::Relaxed), self.hooks_forbidden.load(Ordering::Relaxed), self.hooks_unmatched.load(Ordering::Relaxed), self.commands_executed.load(Ordering::Relaxed), self.commands_execution_failed.load(Ordering::Relaxed), self.commands_successful.load(Ordering::Relaxed), self.commands_failed.load(Ordering::Relaxed), ) } }