mirror of https://github.com/telemt/telemt.git
Implement hot-reload for config and log level
Added hot-reload functionality for configuration and log level.
This commit is contained in:
parent
5be81952f3
commit
b8add81018
39
src/main.rs
39
src/main.rs
|
|
@ -27,6 +27,7 @@ mod tls_front;
|
|||
mod util;
|
||||
|
||||
use crate::config::{LogLevel, ProxyConfig};
|
||||
use crate::config::hot_reload::spawn_config_watcher;
|
||||
use crate::crypto::SecureRandom;
|
||||
use crate::ip_tracker::UserIpTracker;
|
||||
use crate::network::probe::{decide_network_capabilities, log_probe_result, run_probe};
|
||||
|
|
@ -469,6 +470,16 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
// Freeze config after possible fallback decision
|
||||
let config = Arc::new(config);
|
||||
|
||||
// ── Hot-reload watcher ────────────────────────────────────────────────
|
||||
// Spawns a background task that watches the config file and reloads it
|
||||
// on SIGHUP (Unix) or every 60 seconds. Each accept-loop clones the
|
||||
// receiver and calls `.borrow_and_update().clone()` per connection.
|
||||
let (config_rx, mut log_level_rx) = spawn_config_watcher(
|
||||
std::path::PathBuf::from(&config_path),
|
||||
config.clone(),
|
||||
std::time::Duration::from_secs(60),
|
||||
);
|
||||
|
||||
let replay_checker = Arc::new(ReplayChecker::new(
|
||||
config.access.replay_check_len,
|
||||
Duration::from_secs(config.access.replay_window_secs),
|
||||
|
|
@ -760,7 +771,7 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
|
||||
has_unix_listener = true;
|
||||
|
||||
let config = config.clone();
|
||||
let mut config_rx_unix = config_rx.clone();
|
||||
let stats = stats.clone();
|
||||
let upstream_manager = upstream_manager.clone();
|
||||
let replay_checker = replay_checker.clone();
|
||||
|
|
@ -779,7 +790,8 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
let conn_id = unix_conn_counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
let fake_peer = SocketAddr::from(([127, 0, 0, 1], (conn_id % 65535) as u16));
|
||||
|
||||
let config = config.clone();
|
||||
// Pick up the latest config atomically for this connection.
|
||||
let config = config_rx_unix.borrow_and_update().clone();
|
||||
let stats = stats.clone();
|
||||
let upstream_manager = upstream_manager.clone();
|
||||
let replay_checker = replay_checker.clone();
|
||||
|
|
@ -813,7 +825,7 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// Switch to user-configured log level after startup
|
||||
// Switch to user-configured log level after startup (before starting listeners)
|
||||
let runtime_filter = if has_rust_log {
|
||||
EnvFilter::from_default_env()
|
||||
} else if matches!(effective_log_level, LogLevel::Silent) {
|
||||
|
|
@ -825,6 +837,22 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
.reload(runtime_filter)
|
||||
.expect("Failed to switch log filter");
|
||||
|
||||
// Apply log_level changes to the tracing reload handle.
|
||||
// Note: the initial runtime_filter is applied below (after startup); this
|
||||
// task handles subsequent hot-reload changes only.
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
if log_level_rx.changed().await.is_err() {
|
||||
break;
|
||||
}
|
||||
let level = log_level_rx.borrow_and_update().clone();
|
||||
let new_filter = tracing_subscriber::EnvFilter::new(level.to_filter_str());
|
||||
if let Err(e) = filter_handle.reload(new_filter) {
|
||||
tracing::error!("config reload: failed to update log filter: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(port) = config.server.metrics_port {
|
||||
let stats = stats.clone();
|
||||
let whitelist = config.server.metrics_whitelist.clone();
|
||||
|
|
@ -834,7 +862,7 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
}
|
||||
|
||||
for listener in listeners {
|
||||
let config = config.clone();
|
||||
let mut config_rx = config_rx.clone();
|
||||
let stats = stats.clone();
|
||||
let upstream_manager = upstream_manager.clone();
|
||||
let replay_checker = replay_checker.clone();
|
||||
|
|
@ -848,7 +876,8 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
|||
loop {
|
||||
match listener.accept().await {
|
||||
Ok((stream, peer_addr)) => {
|
||||
let config = config.clone();
|
||||
// Pick up the latest config atomically for this connection.
|
||||
let config = config_rx.borrow_and_update().clone();
|
||||
let stats = stats.clone();
|
||||
let upstream_manager = upstream_manager.clone();
|
||||
let replay_checker = replay_checker.clone();
|
||||
|
|
|
|||
Loading…
Reference in New Issue