Menu
Public repository / 23447341749e267e6dbb85b2c02caa6b9d729c52
AkurAI-Monitor / src/config.rs
Latest change 8bade644cef8ddaa358cc88eb6017c8e64d5a6e4 - AKURAI-MONITOR-7 monitor processes, docker, systemd; fix #errors alert delivery by Ólafur Búi Ólafsson
use std::sync::LazyLock;
pub struct Config {
pub listen_addr: String,
pub db_url: String,
pub static_dir: String,
pub alert_log: String,
pub log_files: Vec<String>,
pub interval_secs: u64,
pub retention_days: i64,
pub log_retention_days: i64,
pub log_debug_retention_days: i64,
pub log_max_rows: i64,
pub log_stale_secs: i64,
pub journal_replay_secs: i64,
pub oidc_issuer: String,
pub oidc_client_id: String,
pub oidc_client_secret: String,
pub oidc_redirect_uri: String,
pub ingest_token: String,
pub api_token: String,
pub journal_units: Vec<String>,
pub journal_match: Vec<String>,
pub systemd_match: Vec<String>,
pub proc_top_n: usize,
pub pibun_ingest_url: String,
pub pibun_ingest_token: String,
pub pibun_ingest_channel: String,
}
fn cli_overrides(
args: impl Iterator<Item = String>,
) -> (Option<String>, Option<String>, Option<String>) {
let mut static_dir = None;
let mut host = None;
let mut port = None;
let mut args = args.peekable();
while let Some(arg) = args.next() {
let target = match arg.as_str() {
"--dir" => &mut static_dir,
"--host" => &mut host,
"--port" => &mut port,
_ => continue,
};
*target = args.next();
}
(static_dir, host, port)
}
static CONFIG: LazyLock<Config> = LazyLock::new(|| {
let (static_dir, host, port) = cli_overrides(std::env::args().skip(1));
let listen_addr = match (host, port) {
(Some(host), Some(port)) => format!("{host}:{port}"),
_ => std::env::var("MONITOR_LISTEN").unwrap_or_else(|_| "127.0.0.1:8800".to_string()),
};
let log_files_str = std::env::var("MONITOR_LOG_FILES")
.unwrap_or_else(|_| "/var/log/syslog,/var/log/auth.log".to_string());
let log_files: Vec<String> = log_files_str
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
let base_url = std::env::var("MONITOR_BASE_URL")
.unwrap_or_else(|_| "https://monitor.olibuijr.com".to_string())
.trim_end_matches('/')
.to_string();
let redirect_uri = std::env::var("MONITOR_OIDC_REDIRECT_URI")
.unwrap_or_else(|_| format!("{base_url}/auth/callback"));
let journal_match: Vec<String> = std::env::var("MONITOR_JOURNAL_MATCH")
.unwrap_or_else(|_| "akurai-,golfsetrid,rust-monitor".to_string())
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
Config {
listen_addr,
db_url: std::env::var("MONITOR_DB_URL")
.unwrap_or_else(|_| "mysql://monitor@127.0.0.1:3306/akurai_monitor".to_string()),
static_dir: static_dir
.or_else(|| std::env::var("MONITOR_STATIC_DIR").ok())
.unwrap_or_else(|| "./ui".to_string()),
alert_log: std::env::var("MONITOR_ALERT_LOG")
.unwrap_or_else(|_| "./data/alerts.log".to_string()),
log_files,
interval_secs: std::env::var("MONITOR_INTERVAL")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(60),
retention_days: std::env::var("MONITOR_RETENTION_DAYS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(30),
log_retention_days: std::env::var("MONITOR_LOG_RETENTION_DAYS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(7),
log_debug_retention_days: std::env::var("MONITOR_LOG_DEBUG_RETENTION_DAYS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(2),
log_max_rows: std::env::var("MONITOR_LOG_MAX_ROWS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(2_000_000),
log_stale_secs: std::env::var("MONITOR_LOG_STALE_SECS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(900),
journal_replay_secs: std::env::var("MONITOR_JOURNAL_REPLAY_SECS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(300),
oidc_issuer: std::env::var("MONITOR_OIDC_ISSUER")
.unwrap_or_else(|_| "https://auth.olibuijr.com".to_string()),
oidc_client_id: std::env::var("MONITOR_OIDC_CLIENT_ID").unwrap_or_default(),
oidc_client_secret: std::env::var("MONITOR_OIDC_CLIENT_SECRET").unwrap_or_default(),
oidc_redirect_uri: redirect_uri,
ingest_token: std::env::var("MONITOR_INGEST_TOKEN").unwrap_or_default(),
api_token: std::env::var("MONITOR_API_TOKEN").unwrap_or_default(),
journal_units: std::env::var("MONITOR_JOURNAL_UNITS")
.unwrap_or_default()
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect(),
journal_match: journal_match.clone(),
systemd_match: std::env::var("MONITOR_SYSTEMD_MATCH")
.ok()
.map(|raw| {
raw.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect()
})
.unwrap_or(journal_match),
proc_top_n: std::env::var("MONITOR_PROC_TOP_N")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(15),
pibun_ingest_url: std::env::var("MONITOR_PIBUN_INGEST_URL")
.unwrap_or_else(|_| "http://100.88.0.9:4173/api/ingest-error".to_string()),
pibun_ingest_token: std::env::var("MONITOR_PIBUN_INGEST_TOKEN").unwrap_or_default(),
pibun_ingest_channel: std::env::var("MONITOR_PIBUN_INGEST_CHANNEL")
.unwrap_or_else(|_| "errors".to_string()),
}
});
pub fn get() -> &'static Config {
&CONFIG
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deployment_cli_overrides_static_directory_and_listener() {
let args = [
"serve",
"--dir",
"/opt/rust-monitor/app",
"--host",
"127.0.0.1",
"--port",
"8800",
"--name",
"rust-monitor",
]
.into_iter()
.map(str::to_owned);
assert_eq!(
cli_overrides(args),
(
Some("/opt/rust-monitor/app".to_string()),
Some("127.0.0.1".to_string()),
Some("8800".to_string())
)
);
}
}