From 7171f0e94dd9225b50e66b1b8ff173e1ced6d966 Mon Sep 17 00:00:00 2001 From: Andy Nogueira Date: Thu, 3 Jun 2021 07:41:24 -0400 Subject: [PATCH] Add `host` parameter to `telemetry` config (#1033) * Fixing telemetry server listen host (#1032) * Add `host` parameter for the telemetry server * Gracefully exit when telemetry service fails to start Co-authored-by: Romain Ruetschi --- config.toml | 1 + relayer-cli/src/commands/start.rs | 30 ++++++++++++++++++++++-------- relayer/src/config.rs | 2 ++ telemetry/src/lib.rs | 27 ++++++++++++++++++++++++--- telemetry/src/server.rs | 15 ++++++++++----- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/config.toml b/config.toml index b8aa553f4d..ae996198e9 100644 --- a/config.toml +++ b/config.toml @@ -7,6 +7,7 @@ log_level = 'info' [telemetry] enabled = true +host = '127.0.0.1' port = 3001 [[chains]] diff --git a/relayer-cli/src/commands/start.rs b/relayer-cli/src/commands/start.rs index 8190b776d6..72a780f4f8 100644 --- a/relayer-cli/src/commands/start.rs +++ b/relayer-cli/src/commands/start.rs @@ -1,3 +1,5 @@ +use std::error::Error; + use abscissa_core::{Command, Options, Runnable}; use ibc_relayer::config::Config; @@ -13,27 +15,39 @@ impl Runnable for StartCmd { fn run(&self) { let config = app_config(); - let supervisor = spawn_supervisor(config.clone()); - match supervisor.run() { + match spawn_supervisor(config.clone()).and_then(|s| s.run()) { Ok(()) => Output::success_msg("done").exit(), - Err(e) => Output::error(e).exit(), + Err(e) => Output::error(format!("Hermes failed to start, last error: {}", e)).exit(), } } } #[cfg(feature = "telemetry")] -fn spawn_supervisor(config: Config) -> Supervisor { +fn spawn_supervisor(config: Config) -> Result> { let state = ibc_telemetry::new_state(); if config.telemetry.enabled { - ibc_telemetry::spawn(config.telemetry.port, state.clone()); + let address = (config.telemetry.host.clone(), config.telemetry.port); + + match ibc_telemetry::spawn(address, state.clone()) { + Ok((addr, _)) => { + info!( + "telemetry service running, exposing metrics at {}/metrics", + addr + ); + } + Err(e) => { + error!("telemetry service failed to start: {}", e); + return Err(e); + } + } } - Supervisor::spawn(config, state) + Ok(Supervisor::spawn(config, state)) } #[cfg(not(feature = "telemetry"))] -fn spawn_supervisor(config: Config) -> Supervisor { +fn spawn_supervisor(config: Config) -> Result> { if config.telemetry.enabled { warn!( "telemetry enabled in the config but Hermes was built without telemetry support, \ @@ -42,5 +56,5 @@ fn spawn_supervisor(config: Config) -> Supervisor { } let telemetry = ibc_relayer::telemetry::TelemetryDisabled; - Supervisor::spawn(config, telemetry) + Ok(Supervisor::spawn(config, telemetry)) } diff --git a/relayer/src/config.rs b/relayer/src/config.rs index bd5e9c40a0..b756eaab06 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -92,6 +92,7 @@ impl Default for GlobalConfig { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct TelemetryConfig { pub enabled: bool, + pub host: String, pub port: u16, } @@ -99,6 +100,7 @@ impl Default for TelemetryConfig { fn default() -> Self { Self { enabled: false, + host: "127.0.0.1".to_string(), port: 3001, } } diff --git a/telemetry/src/lib.rs b/telemetry/src/lib.rs index 446d566761..593901475c 100644 --- a/telemetry/src/lib.rs +++ b/telemetry/src/lib.rs @@ -1,7 +1,12 @@ pub mod server; pub mod state; -use std::{sync::Arc, thread::JoinHandle}; +use std::{ + error::Error, + net::{SocketAddr, ToSocketAddrs}, + sync::Arc, + thread::JoinHandle, +}; pub use crate::state::TelemetryState; @@ -9,6 +14,22 @@ pub fn new_state() -> Arc { Arc::new(TelemetryState::default()) } -pub fn spawn(port: u16, state: Arc) -> JoinHandle<()> { - std::thread::spawn(move || server::run(state, port)) +pub fn spawn( + address: A, + state: Arc, +) -> Result<(SocketAddr, JoinHandle<()>), Box> +where + A: ToSocketAddrs + Send + 'static, +{ + let server = server::listen(address, state); + + match server { + Ok(server) => { + let address = server.server_addr(); + let handle = std::thread::spawn(move || server.run()); + + Ok((address, handle)) + } + Err(e) => Err(e), + } } diff --git a/telemetry/src/server.rs b/telemetry/src/server.rs index a0fc153e9d..31adcf2338 100644 --- a/telemetry/src/server.rs +++ b/telemetry/src/server.rs @@ -1,7 +1,7 @@ -use std::sync::Arc; +use std::{error::Error, net::ToSocketAddrs, sync::Arc}; use prometheus::{Encoder, TextEncoder}; -use rouille::Request; +use rouille::{Request, Response, Server}; use crate::state::TelemetryState; @@ -20,8 +20,11 @@ impl Route { } } -pub fn run(telemetry_state: Arc, port: u16) { - rouille::start_server(("localhost", port), move |request| { +pub fn listen( + address: impl ToSocketAddrs, + telemetry_state: Arc, +) -> Result Response>, Box> { + let server = Server::new(address, move |request| { match Route::from_request(request) { // The prometheus endpoint Route::Metrics => { @@ -37,5 +40,7 @@ pub fn run(telemetry_state: Arc, port: u16) { // Return an empty response with a 404 status code. Route::Other => rouille::Response::empty_404(), } - }) + })?; + + Ok(server) }