mirror of
https://github.com/sadoyan/aralez.git
synced 2026-10-23 14:11:35 +08:00
Improved error handling, anti unwrap()-ing
This commit is contained in:
+4
-3
@@ -1,5 +1,6 @@
|
||||
use crate::utils::hcclient::{HttpClientRequest, httpclient};
|
||||
use crate::utils::lazylock::{GLOBAL_PARAMS, MASTER_KEY, WORKERS};
|
||||
use crate::utils::tools::Die;
|
||||
use crate::utils::types::{Consul, Extraparams, Headers, Kubernetes, UpstreamsDashMap};
|
||||
use bytes::Bytes;
|
||||
use log::{error, info, warn};
|
||||
@@ -44,7 +45,7 @@ pub struct SendConfigDto {
|
||||
}
|
||||
|
||||
pub fn serialize_config(data: &UpstreamsDashMap) -> String {
|
||||
let config = GLOBAL_PARAMS.read().unwrap();
|
||||
let config = GLOBAL_PARAMS.read().die("Failed to read config");
|
||||
let mut snapshot: HashMap<String, UpstreamConfigDto> = HashMap::new();
|
||||
|
||||
for outer_entry in data.iter() {
|
||||
@@ -268,7 +269,7 @@ pub fn to_yaml(config: &SendConfigDto) -> String {
|
||||
}
|
||||
|
||||
pub async fn send_to_worker(data: String) {
|
||||
let masterkey = MASTER_KEY.get().expect("Master key not set");
|
||||
let masterkey = MASTER_KEY.get().die("Master key not set");
|
||||
if let Some(workers) = WORKERS.get() {
|
||||
for worker in workers {
|
||||
let prefix = if worker.tls { "https://" } else { "http://" };
|
||||
@@ -282,7 +283,7 @@ pub async fn send_to_worker(data: String) {
|
||||
port: worker.port,
|
||||
url: worker_url.as_str(),
|
||||
payload: Bytes::from(data.clone()),
|
||||
headers: Some(vec![("API-KEY", masterkey.clone().expect("Master key must be set in the cluster mode").deref())]),
|
||||
headers: Some(vec![("API-KEY", masterkey.clone().die("Master key must be set in the cluster mode").deref())]),
|
||||
})
|
||||
.await;
|
||||
if (200..500).contains(&status.2) {
|
||||
|
||||
+17
-10
@@ -1,23 +1,30 @@
|
||||
use bytes::Bytes;
|
||||
use http_body_util::Full;
|
||||
use hyper::Request;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use hyper_util::client::legacy::Client;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use log::error;
|
||||
|
||||
pub async fn ping_grpc(addr: &str) -> bool {
|
||||
let connector = HttpConnector::new();
|
||||
let client = Client::builder(TokioExecutor::new()).http2_only(true).build(connector);
|
||||
let uri = format!("{}{}", addr, "/aralez.Probe/Ping");
|
||||
let body = Full::new(Bytes::from(vec![0, 0, 0, 0, 0]));
|
||||
let request = Request::post(uri).header("content-type", "application/grpc").header("te", "trailers").body(body).unwrap();
|
||||
match client.request(request).await {
|
||||
Ok(resp) => resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|v| v.starts_with("application/grpc"))
|
||||
.unwrap_or(false),
|
||||
Err(_) => false,
|
||||
|
||||
match Request::post(uri.clone()).header("content-type", "application/grpc").header("te", "trailers").body(body) {
|
||||
Ok(request) => match client.request(request).await {
|
||||
Ok(resp) => resp
|
||||
.headers()
|
||||
.get("content-type")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|v| v.starts_with("application/grpc"))
|
||||
.unwrap_or(false),
|
||||
Err(_) => false,
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to create request: {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ async fn detect_tls(ip: &str, port: &u16, sni: &str) -> bool {
|
||||
.danger_accept_invalid_certs(true)
|
||||
.danger_accept_invalid_hostnames(true)
|
||||
.build()
|
||||
.unwrap(),
|
||||
.die("Failed to create TLS connector"),
|
||||
);
|
||||
connector.connect(sni, stream).await.is_ok()
|
||||
}
|
||||
|
||||
+31
-18
@@ -1,9 +1,10 @@
|
||||
use crate::utils::lazylock::EVICTION;
|
||||
use crate::utils::tools::Die;
|
||||
use pingora_cache::eviction::EvictionManager;
|
||||
use pingora_http::Method;
|
||||
use pingora_http::StatusCode;
|
||||
use pingora_http::Version;
|
||||
use prometheus::{register_histogram, register_int_counter, register_int_counter_vec, register_int_gauge, Histogram, IntCounter, IntCounterVec, IntGauge};
|
||||
use prometheus::{Histogram, IntCounter, IntCounterVec, IntGauge, register_histogram, register_int_counter, register_int_counter_vec, register_int_gauge};
|
||||
use std::sync::Arc;
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Duration;
|
||||
@@ -16,19 +17,28 @@ pub struct MetricTypes {
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
pub static OPEN_FILES: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_open_files", "Number of open file descriptors").unwrap());
|
||||
pub static LOGGING_ERRORS: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_logging_errors", "Number of log errors").unwrap());
|
||||
pub static MEMORY_USAGE: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_memory_bytes", "Total memory allocated in bytes").unwrap());
|
||||
pub static ACTIVE_SESSIONS: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_active_sessions", "Current number of active sessions").unwrap());
|
||||
pub static REQUEST_COUNT: LazyLock<IntCounter> = LazyLock::new(|| register_int_counter!("aralez_requests_total", "Total number of requests handled by Aralez").unwrap());
|
||||
pub static OPEN_FILES: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_open_files", "Number of open file descriptors").die("Failed to register OPEN_FILES metric"));
|
||||
pub static LOGGING_ERRORS: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_logging_errors", "Number of log errors").die("Failed to register LOGGING_ERRORS metric"));
|
||||
pub static MEMORY_USAGE: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_memory_bytes", "Total memory allocated in bytes").die("Failed to register MEMORY_USAGE metric"));
|
||||
pub static ACTIVE_SESSIONS: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_active_sessions", "Current number of active sessions").die("Failed to register ACTIVE_SESSIONS metric"));
|
||||
pub static REQUEST_COUNT: LazyLock<IntCounter> =
|
||||
LazyLock::new(|| register_int_counter!("aralez_requests_total", "Total number of requests handled by Aralez").die("Failed to register REQUEST_COUNT metric"));
|
||||
|
||||
pub static CACHE_SIZE_BYTES: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_cache_size_bytes", "Current cache size in bytes").unwrap());
|
||||
pub static CACHE_ITEMS: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_cache_items", "Current number of cached objects").unwrap());
|
||||
pub static CACHE_EVICTED_BYTES: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_cache_evicted_bytes_total", "Total bytes evicted from cache").unwrap());
|
||||
pub static CACHE_SIZE_BYTES: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_cache_size_bytes", "Current cache size in bytes").die("Failed to register CACHE_SIZE_BYTES metric"));
|
||||
pub static CACHE_ITEMS: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_cache_items", "Current number of cached objects").die("Failed to register CACHE_ITEMS metric"));
|
||||
pub static CACHE_EVICTED_BYTES: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_cache_evicted_bytes_total", "Total bytes evicted from cache").die("Failed to register CACHE_EVICTED_BYTES metric"));
|
||||
|
||||
pub static CACHE_EVICTED_ITEMS: LazyLock<IntGauge> = LazyLock::new(|| register_int_gauge!("aralez_cache_evicted_items_total", "Total cache items evicted").unwrap());
|
||||
pub static CACHE_EVICTED_ITEMS: LazyLock<IntGauge> =
|
||||
LazyLock::new(|| register_int_gauge!("aralez_cache_evicted_items_total", "Total cache items evicted").die("Failed to register CACHE_EVICTED_ITEMS metric"));
|
||||
pub static RESPONSE_CODES: LazyLock<IntCounterVec> =
|
||||
LazyLock::new(|| register_int_counter_vec!("aralez_responses_total", "Responses grouped by status code", &["status"]).unwrap());
|
||||
LazyLock::new(|| register_int_counter_vec!("aralez_responses_total", "Responses grouped by status code", &["status"]).die("Failed to register RESPONSE_CODES metric"));
|
||||
|
||||
pub static RESPONSE_LATENCY: LazyLock<Histogram> = LazyLock::new(|| {
|
||||
register_histogram!(
|
||||
@@ -36,17 +46,20 @@ pub static RESPONSE_LATENCY: LazyLock<Histogram> = LazyLock::new(|| {
|
||||
"Response latency in seconds",
|
||||
vec![0.001, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 1.0, 2.0, 5.0]
|
||||
)
|
||||
.unwrap()
|
||||
.die("Failed to register RESPONSE_LATENCY metric")
|
||||
});
|
||||
|
||||
pub static REQUESTS_BY_METHOD: LazyLock<IntCounterVec> =
|
||||
LazyLock::new(|| register_int_counter_vec!("aralez_requests_by_method_total", "Number of requests by HTTP method", &["method"]).unwrap());
|
||||
pub static REQUESTS_BY_METHOD: LazyLock<IntCounterVec> = LazyLock::new(|| {
|
||||
register_int_counter_vec!("aralez_requests_by_method_total", "Number of requests by HTTP method", &["method"]).die("Failed to register REQUESTS_BY_METHOD metric")
|
||||
});
|
||||
|
||||
pub static REQUESTS_BY_UPSTREAM: LazyLock<IntCounterVec> =
|
||||
LazyLock::new(|| register_int_counter_vec!("aralez_requests_by_upstream", "Number of requests by UPSTREAM server", &["upstream"]).unwrap());
|
||||
pub static REQUESTS_BY_UPSTREAM: LazyLock<IntCounterVec> = LazyLock::new(|| {
|
||||
register_int_counter_vec!("aralez_requests_by_upstream", "Number of requests by UPSTREAM server", &["upstream"]).die("Failed to register REQUESTS_BY_UPSTREAM metric")
|
||||
});
|
||||
|
||||
pub static REQUESTS_BY_VERSION: LazyLock<IntCounterVec> =
|
||||
LazyLock::new(|| register_int_counter_vec!("aralez_requests_by_version_total", "Number of requests by HTTP versions", &["version"]).unwrap());
|
||||
pub static REQUESTS_BY_VERSION: LazyLock<IntCounterVec> = LazyLock::new(|| {
|
||||
register_int_counter_vec!("aralez_requests_by_version_total", "Number of requests by HTTP versions", &["version"]).die("Failed to register REQUESTS_BY_VERSION metric")
|
||||
});
|
||||
pub static HTTP_11_COUNT: LazyLock<IntCounter> = LazyLock::new(|| REQUESTS_BY_VERSION.with_label_values(&["HTTP/1.1"]));
|
||||
pub static HTTP_20_COUNT: LazyLock<IntCounter> = LazyLock::new(|| REQUESTS_BY_VERSION.with_label_values(&["HTTP/2.0"]));
|
||||
pub static HTTP_30_COUNT: LazyLock<IntCounter> = LazyLock::new(|| REQUESTS_BY_VERSION.with_label_values(&["HTTP/3.0"]));
|
||||
|
||||
@@ -48,8 +48,8 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
||||
return (None, err_msg);
|
||||
}
|
||||
|
||||
let mut confdir = Path::new(d).parent().unwrap().to_path_buf();
|
||||
let mut autocfg = Path::new(d).parent().unwrap().to_path_buf();
|
||||
let mut confdir = Path::new(d).parent().die("Invalid configuration path").to_path_buf();
|
||||
let mut autocfg = Path::new(d).parent().die("Invalid configuration path").to_path_buf();
|
||||
|
||||
autocfg.push("autoconfigs");
|
||||
if fs::metadata(autocfg.clone()).is_err() {
|
||||
|
||||
+3
-2
@@ -1,3 +1,4 @@
|
||||
use crate::utils::tools::Die;
|
||||
use std::sync::{LazyLock, RwLock};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -8,11 +9,11 @@ pub struct SharedState {
|
||||
pub static GLOBAL_STATE: LazyLock<RwLock<SharedState>> = LazyLock::new(|| RwLock::new(SharedState { first_run: true }));
|
||||
|
||||
pub fn mark_not_first_run() {
|
||||
let mut state = GLOBAL_STATE.write().unwrap();
|
||||
let mut state = GLOBAL_STATE.write().die("Writing global state failed");
|
||||
state.first_run = false;
|
||||
}
|
||||
|
||||
pub fn is_first_run() -> bool {
|
||||
let state = GLOBAL_STATE.read().unwrap();
|
||||
let state = GLOBAL_STATE.read().die("Writing global state failed");
|
||||
state.first_run
|
||||
}
|
||||
|
||||
+14
-11
@@ -14,6 +14,7 @@ use std::net::SocketAddr;
|
||||
use std::net::TcpListener;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::panic::Location;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
@@ -23,9 +24,9 @@ use std::{env, fs, process, thread, time};
|
||||
pub fn print_upstreams(upstreams: &UpstreamsDashMap, extraparams: &Extraparams) {
|
||||
let mut out = String::new();
|
||||
for host_entry in upstreams.iter() {
|
||||
writeln!(out, "Hostname: {}", host_entry.key()).unwrap();
|
||||
writeln!(out, "Hostname: {}", host_entry.key()).unwrap_or_default();
|
||||
for path_entry in host_entry.value().iter() {
|
||||
writeln!(out, " Path: {}", path_entry.key()).unwrap();
|
||||
writeln!(out, " Path: {}", path_entry.key()).unwrap_or_default();
|
||||
for f in path_entry.value().0.clone() {
|
||||
writeln!(
|
||||
out,
|
||||
@@ -38,7 +39,7 @@ pub fn print_upstreams(upstreams: &UpstreamsDashMap, extraparams: &Extraparams)
|
||||
if f.rate_limit > 0 { f.rate_limit } else { extraparams.rate_limit },
|
||||
if f.x4xx_limit > 0 { f.x4xx_limit } else { extraparams.x4xx_limit }
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +162,9 @@ pub fn clone_idmap_into(original: &UpstreamsDashMap, cloned: &UpstreamsIdMap) {
|
||||
pub fn listdir(dir: String) -> Vec<load::CertificateConfig> {
|
||||
let mut f = HashMap::new();
|
||||
let mut certificate_configs: Vec<load::CertificateConfig> = vec![];
|
||||
let paths = fs::read_dir(dir).unwrap();
|
||||
let paths = fs::read_dir(dir).die("listing certificates directory failed");
|
||||
for path in paths {
|
||||
let path_str = path.unwrap().path().to_str().unwrap().to_owned();
|
||||
let path_str = path.die("getting certs path").path().to_str().die("certs pat t &str").to_owned();
|
||||
if path_str.ends_with(".crt") {
|
||||
let name = path_str.replace(".crt", "");
|
||||
let mut inner = vec![];
|
||||
@@ -212,9 +213,9 @@ pub fn drop_priv(user: String, group: String, http_addr: String, tls_addr: Optio
|
||||
}
|
||||
|
||||
pub fn check_priv(addr: &str) {
|
||||
let port = SocketAddr::from_str(addr).map(|sa| sa.port()).expect("Failed to parse address port ");
|
||||
let port = SocketAddr::from_str(addr).map(|sa| sa.port()).die("Failed to parse address port ");
|
||||
if port < 1024 {
|
||||
let meta = std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap();
|
||||
let meta = std::fs::metadata("/proc/self").map(|m| m.uid()).die("Reading /proc/self");
|
||||
if meta != 0 {
|
||||
error!("Running on privileged port requires to start as ROOT");
|
||||
process::exit(1)
|
||||
@@ -369,18 +370,19 @@ pub fn get_hostname() -> String {
|
||||
// log::error!("{message}");
|
||||
// process::exit(1);
|
||||
// }
|
||||
// ========================================= //
|
||||
|
||||
pub trait Die<T> {
|
||||
fn die(self, message: &str) -> T;
|
||||
}
|
||||
|
||||
impl<T, E: Debug> Die<T> for Result<T, E> {
|
||||
#[track_caller]
|
||||
fn die(self, message: &str) -> T {
|
||||
match self {
|
||||
Ok(value) => value,
|
||||
Err(e) => {
|
||||
eprintln!("\x1b[1;31mERROR:\x1b[0m {message}: {e:?}");
|
||||
let loc = Location::caller();
|
||||
eprintln!("\x1b[1;31mERROR:\x1b[0m {message}: {e:?}: {}: {}", loc.file(), loc.line());
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
@@ -388,14 +390,15 @@ impl<T, E: Debug> Die<T> for Result<T, E> {
|
||||
}
|
||||
|
||||
impl<T> Die<T> for Option<T> {
|
||||
#[track_caller]
|
||||
fn die(self, message: &str) -> T {
|
||||
match self {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
eprintln!("\x1b[1;31mERROR:\x1b[0m {message}");
|
||||
let loc = Location::caller();
|
||||
eprintln!("\x1b[1;31mERROR:\x1b[0m {message} at {}:{}", loc.file(), loc.line());
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ========================================= //
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
use crate::tls::CertificateConfig;
|
||||
use crate::utils::parceyaml::load_configuration;
|
||||
use crate::utils::tools::listdir;
|
||||
use crate::utils::tools::{Die, listdir};
|
||||
use crate::utils::types::Configuration;
|
||||
use log::{error, info};
|
||||
use notify::event::ModifyKind;
|
||||
@@ -15,7 +15,7 @@ use tokio::task;
|
||||
pub async fn file_watch(fp: String, toreturn: Sender<Configuration>) {
|
||||
sleep(Duration::from_millis(50)).await; // For having nice logs :-)
|
||||
let file_path = fp.as_str();
|
||||
let parent_dir = Path::new(file_path).parent().unwrap();
|
||||
let parent_dir = Path::new(file_path).parent().die("Get parent folder");
|
||||
let (local_tx, mut local_rx) = tokio::sync::mpsc::channel::<notify::Result<Event>>(1);
|
||||
|
||||
let _watcher_handle = task::spawn_blocking({
|
||||
@@ -27,8 +27,8 @@ pub async fn file_watch(fp: String, toreturn: Sender<Configuration>) {
|
||||
},
|
||||
Config::default(),
|
||||
)
|
||||
.unwrap();
|
||||
watcher.watch(&parent_dir, RecursiveMode::Recursive).unwrap();
|
||||
.die("Initialize file watcher");
|
||||
watcher.watch(&parent_dir, RecursiveMode::Recursive).die("");
|
||||
let (_rtx, mut rrx) = tokio::sync::mpsc::channel::<bool>(1);
|
||||
let _ = rrx.blocking_recv();
|
||||
}
|
||||
@@ -42,7 +42,7 @@ pub async fn file_watch(fp: String, toreturn: Sender<Configuration>) {
|
||||
start = Instant::now();
|
||||
let snd = load_configuration(file_path, "filepath").await.0;
|
||||
if let Some(snd) = snd {
|
||||
toreturn.send(snd).await.unwrap();
|
||||
toreturn.send(snd).await.die("Send to file watcher");
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
||||
Reference in New Issue
Block a user