feat(relay): serve metrics conditionally based on passed socket addr (#1833)

While developing IPv6 support, I ran into a limitations with how I
designed the prometheus metrics integration. Currently, we just use the
IPv4 listen socket to server the metrics. That however no longer works
with IPv6 support because the relay may now operate in IPv6 only mode
for example.

To circumvent this, we introduce a dedicated configuration option where
the user needs to pass the socket addr for the metrics endpoint. If
omitted, the metrics won't be served at all.
This commit is contained in:
Thomas Eizinger
2023-07-31 22:21:29 +02:00
committed by GitHub
parent 73e60795d8
commit e24b3ac39b
2 changed files with 11 additions and 5 deletions

View File

@@ -32,6 +32,11 @@ struct Args {
/// Must not be a wildcard-address.
#[arg(long, env)]
listen_ip4_addr: Ipv4Addr,
/// The address of the local interface where we should serve the prometheus metrics.
///
/// The metrics will be available at `http://<metrics_addr>/metrics`.
#[arg(long, env)]
metrics_addr: Option<SocketAddr>,
/// The websocket URL of the portal server to connect to.
#[arg(long, env, default_value = "wss://api.firezone.dev")]
portal_ws_url: Url,
@@ -134,7 +139,10 @@ async fn main() -> Result<()> {
let mut eventloop =
Eventloop::new(server, channel, args.listen_ip4_addr, &mut metric_registry).await?;
tokio::spawn(relay::metrics::serve(args.listen_ip4_addr, metric_registry));
if let Some(metrics_addr) = args.metrics_addr {
tokio::spawn(relay::metrics::serve(metrics_addr, metric_registry));
}
tracing::info!("Listening for incoming traffic on UDP port 3478");

View File

@@ -5,15 +5,13 @@ use axum::response::IntoResponse;
use axum::routing::get;
use axum::{Router, Server};
use prometheus_client::registry::Registry;
use std::net::{IpAddr, SocketAddr};
use std::net::SocketAddr;
use std::sync::Arc;
const CONTENT_TYPE: &str = "application/openmetrics-text;charset=utf-8;version=1.0.0";
const PORT: u16 = 8080;
pub async fn serve(addr: impl Into<IpAddr>, registry: Registry) -> Result<()> {
pub async fn serve(addr: impl Into<SocketAddr>, registry: Registry) -> Result<()> {
let addr = addr.into();
let addr = SocketAddr::new(addr, PORT);
let service = Router::new()
.route("/metrics", get(metrics))