mirror of https://github.com/telemt/telemt.git
Update metrics configuration to support custom listen address
- Bump telemt dependency version from 3.3.15 to 3.3.19. - Add `metrics_listen` option to `config.toml` for specifying a custom address for the metrics endpoint. - Update `ServerConfig` struct to include `metrics_listen` and adjust logic in `spawn_metrics_if_configured` to prioritize this new option over `metrics_port`. - Enhance error handling for invalid listen addresses in metrics setup.
This commit is contained in:
parent
95c1306166
commit
a74def9561
|
|
@ -2087,7 +2087,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "telemt"
|
name = "telemt"
|
||||||
version = "3.3.15"
|
version = "3.3.19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ show = "*"
|
||||||
port = 443
|
port = 443
|
||||||
# proxy_protocol = false # Enable if behind HAProxy/nginx with PROXY protocol
|
# proxy_protocol = false # Enable if behind HAProxy/nginx with PROXY protocol
|
||||||
# metrics_port = 9090
|
# metrics_port = 9090
|
||||||
|
# metrics_listen = "0.0.0.0:9090" # Listen address for metrics (overrides metrics_port)
|
||||||
# metrics_whitelist = ["127.0.0.1", "::1", "0.0.0.0/0"]
|
# metrics_whitelist = ["127.0.0.1", "::1", "0.0.0.0/0"]
|
||||||
|
|
||||||
[server.api]
|
[server.api]
|
||||||
|
|
|
||||||
|
|
@ -1156,9 +1156,17 @@ pub struct ServerConfig {
|
||||||
#[serde(default = "default_proxy_protocol_header_timeout_ms")]
|
#[serde(default = "default_proxy_protocol_header_timeout_ms")]
|
||||||
pub proxy_protocol_header_timeout_ms: u64,
|
pub proxy_protocol_header_timeout_ms: u64,
|
||||||
|
|
||||||
|
/// Port for the Prometheus-compatible metrics endpoint.
|
||||||
|
/// Enables metrics when set; binds on all interfaces (dual-stack) by default.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub metrics_port: Option<u16>,
|
pub metrics_port: Option<u16>,
|
||||||
|
|
||||||
|
/// Listen address for metrics in `IP:PORT` format (e.g. `"127.0.0.1:9090"`).
|
||||||
|
/// When set, takes precedence over `metrics_port` and binds on the specified address only.
|
||||||
|
#[serde(default)]
|
||||||
|
pub metrics_listen: Option<String>,
|
||||||
|
|
||||||
|
/// CIDR whitelist for the metrics endpoint.
|
||||||
#[serde(default = "default_metrics_whitelist")]
|
#[serde(default = "default_metrics_whitelist")]
|
||||||
pub metrics_whitelist: Vec<IpNetwork>,
|
pub metrics_whitelist: Vec<IpNetwork>,
|
||||||
|
|
||||||
|
|
@ -1186,6 +1194,7 @@ impl Default for ServerConfig {
|
||||||
proxy_protocol: false,
|
proxy_protocol: false,
|
||||||
proxy_protocol_header_timeout_ms: default_proxy_protocol_header_timeout_ms(),
|
proxy_protocol_header_timeout_ms: default_proxy_protocol_header_timeout_ms(),
|
||||||
metrics_port: None,
|
metrics_port: None,
|
||||||
|
metrics_listen: None,
|
||||||
metrics_whitelist: default_metrics_whitelist(),
|
metrics_whitelist: default_metrics_whitelist(),
|
||||||
api: ApiConfig::default(),
|
api: ApiConfig::default(),
|
||||||
listeners: Vec::new(),
|
listeners: Vec::new(),
|
||||||
|
|
|
||||||
|
|
@ -279,11 +279,32 @@ pub(crate) async fn spawn_metrics_if_configured(
|
||||||
ip_tracker: Arc<UserIpTracker>,
|
ip_tracker: Arc<UserIpTracker>,
|
||||||
config_rx: watch::Receiver<Arc<ProxyConfig>>,
|
config_rx: watch::Receiver<Arc<ProxyConfig>>,
|
||||||
) {
|
) {
|
||||||
if let Some(port) = config.server.metrics_port {
|
// metrics_listen takes precedence; fall back to metrics_port for backward compat.
|
||||||
|
let metrics_target: Option<(u16, Option<String>)> =
|
||||||
|
if let Some(ref listen) = config.server.metrics_listen {
|
||||||
|
match listen.parse::<std::net::SocketAddr>() {
|
||||||
|
Ok(addr) => Some((addr.port(), Some(listen.clone()))),
|
||||||
|
Err(e) => {
|
||||||
|
startup_tracker
|
||||||
|
.skip_component(
|
||||||
|
COMPONENT_METRICS_START,
|
||||||
|
Some(format!("invalid metrics_listen \"{}\": {}", listen, e)),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config.server.metrics_port.map(|p| (p, None))
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some((port, listen)) = metrics_target {
|
||||||
|
let fallback_label = format!("port {}", port);
|
||||||
|
let label = listen.as_deref().unwrap_or(&fallback_label);
|
||||||
startup_tracker
|
startup_tracker
|
||||||
.start_component(
|
.start_component(
|
||||||
COMPONENT_METRICS_START,
|
COMPONENT_METRICS_START,
|
||||||
Some(format!("spawn metrics endpoint on {}", port)),
|
Some(format!("spawn metrics endpoint on {}", label)),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let stats = stats.clone();
|
let stats = stats.clone();
|
||||||
|
|
@ -294,6 +315,7 @@ pub(crate) async fn spawn_metrics_if_configured(
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
metrics::serve(
|
metrics::serve(
|
||||||
port,
|
port,
|
||||||
|
listen,
|
||||||
stats,
|
stats,
|
||||||
beobachten,
|
beobachten,
|
||||||
ip_tracker_metrics,
|
ip_tracker_metrics,
|
||||||
|
|
@ -308,7 +330,7 @@ pub(crate) async fn spawn_metrics_if_configured(
|
||||||
Some("metrics task spawned".to_string()),
|
Some("metrics task spawned".to_string()),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
} else {
|
} else if config.server.metrics_listen.is_none() {
|
||||||
startup_tracker
|
startup_tracker
|
||||||
.skip_component(
|
.skip_component(
|
||||||
COMPONENT_METRICS_START,
|
COMPONENT_METRICS_START,
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use crate::transport::{ListenOptions, create_listener};
|
||||||
|
|
||||||
pub async fn serve(
|
pub async fn serve(
|
||||||
port: u16,
|
port: u16,
|
||||||
|
listen: Option<String>,
|
||||||
stats: Arc<Stats>,
|
stats: Arc<Stats>,
|
||||||
beobachten: Arc<BeobachtenStore>,
|
beobachten: Arc<BeobachtenStore>,
|
||||||
ip_tracker: Arc<UserIpTracker>,
|
ip_tracker: Arc<UserIpTracker>,
|
||||||
|
|
@ -28,6 +29,33 @@ pub async fn serve(
|
||||||
whitelist: Vec<IpNetwork>,
|
whitelist: Vec<IpNetwork>,
|
||||||
) {
|
) {
|
||||||
let whitelist = Arc::new(whitelist);
|
let whitelist = Arc::new(whitelist);
|
||||||
|
|
||||||
|
// If `metrics_listen` is set, bind on that single address only.
|
||||||
|
if let Some(ref listen_addr) = listen {
|
||||||
|
let addr: SocketAddr = match listen_addr.parse() {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(e) => {
|
||||||
|
warn!(error = %e, "Invalid metrics_listen address: {}", listen_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let is_ipv6 = addr.is_ipv6();
|
||||||
|
match bind_metrics_listener(addr, is_ipv6) {
|
||||||
|
Ok(listener) => {
|
||||||
|
info!("Metrics endpoint: http://{}/metrics and /beobachten", addr);
|
||||||
|
serve_listener(
|
||||||
|
listener, stats, beobachten, ip_tracker, config_rx, whitelist,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!(error = %e, "Failed to bind metrics on {}", addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: bind on 0.0.0.0 and [::] using metrics_port.
|
||||||
let mut listener_v4 = None;
|
let mut listener_v4 = None;
|
||||||
let mut listener_v6 = None;
|
let mut listener_v6 = None;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue