forked from lavina/lavina
clean stuff, move metrics endpoint onto a separate port
This commit is contained in:
parent
e0ae11c02d
commit
08fe958d60
|
@ -1,5 +1,5 @@
|
||||||
[cluster]
|
[telemetry]
|
||||||
name = "localhost"
|
listen_on = "127.0.0.1:8080"
|
||||||
servers = ["127.0.0.1:3333"]
|
|
||||||
|
|
||||||
|
|
||||||
|
[irc]
|
||||||
|
listen_on = "127.0.0.1:6667"
|
||||||
|
|
121
src/http.rs
121
src/http.rs
|
@ -1,121 +0,0 @@
|
||||||
use crate::core::player::PlayerRegistry;
|
|
||||||
use crate::core::room::*;
|
|
||||||
use crate::prelude::*;
|
|
||||||
use crate::projections::trivial::handle_request;
|
|
||||||
|
|
||||||
use std::convert::Infallible;
|
|
||||||
|
|
||||||
use http_body_util::{BodyExt, Full};
|
|
||||||
use hyper::server::conn::http1;
|
|
||||||
use hyper::{body::Bytes, service::service_fn, Request, Response};
|
|
||||||
use hyper::{Method, StatusCode};
|
|
||||||
|
|
||||||
use prometheus::{Encoder, IntGauge, Opts, Registry as MetricsRegistry, TextEncoder};
|
|
||||||
use tokio::net::TcpListener;
|
|
||||||
use tokio::sync::oneshot::Sender;
|
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
|
|
||||||
type BoxBody = http_body_util::combinators::BoxBody<Bytes, Infallible>;
|
|
||||||
|
|
||||||
async fn hello(
|
|
||||||
_: Request<hyper::body::Incoming>,
|
|
||||||
) -> std::result::Result<Response<Full<Bytes>>, Infallible> {
|
|
||||||
Ok(Response::new(Full::new(Bytes::from("Hello World!"))))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn not_found() -> std::result::Result<Response<Full<Bytes>>, Infallible> {
|
|
||||||
let mut response = Response::new(Full::new(Bytes::from("404")));
|
|
||||||
*response.status_mut() = StatusCode::NOT_FOUND;
|
|
||||||
Ok(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn metrics(registry: MetricsRegistry) -> std::result::Result<Response<Full<Bytes>>, Infallible> {
|
|
||||||
let mf = registry.gather();
|
|
||||||
let mut buffer = vec![];
|
|
||||||
let encoder = TextEncoder::new();
|
|
||||||
encoder
|
|
||||||
.encode(&mf, &mut buffer)
|
|
||||||
.expect("write to vec cannot fail");
|
|
||||||
|
|
||||||
Ok(Response::new(Full::new(Bytes::from(buffer))))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn route(
|
|
||||||
registry: MetricsRegistry,
|
|
||||||
chats: PlayerRegistry,
|
|
||||||
request: Request<hyper::body::Incoming>,
|
|
||||||
) -> std::result::Result<Response<BoxBody>, Infallible> {
|
|
||||||
match (request.method(), request.uri().path()) {
|
|
||||||
(&Method::GET, "/hello") => Ok(hello(request).await?.map(BodyExt::boxed)),
|
|
||||||
(&Method::GET, "/socket") => Ok(handle_request(request, chats).await?.map(BodyExt::boxed)),
|
|
||||||
(&Method::GET, "/metrics") => Ok(metrics(registry)?.map(BodyExt::boxed)),
|
|
||||||
_ => Ok(not_found()?.map(BodyExt::boxed)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct HttpServerActor {
|
|
||||||
terminator: Sender<()>,
|
|
||||||
fiber: JoinHandle<Result<()>>,
|
|
||||||
}
|
|
||||||
impl HttpServerActor {
|
|
||||||
pub async fn launch(
|
|
||||||
listener: TcpListener,
|
|
||||||
metrics: MetricsRegistry,
|
|
||||||
rooms: RoomRegistry,
|
|
||||||
players: PlayerRegistry,
|
|
||||||
) -> Result<HttpServerActor> {
|
|
||||||
let (terminator, receiver) = tokio::sync::oneshot::channel::<()>();
|
|
||||||
let fiber =
|
|
||||||
tokio::task::spawn(Self::main_loop(listener, receiver, metrics, rooms, players));
|
|
||||||
Ok(HttpServerActor { terminator, fiber })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn terminate(self) -> Result<()> {
|
|
||||||
match self.terminator.send(()) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(_) => failure("wat")?,
|
|
||||||
}
|
|
||||||
self.fiber.await??;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn main_loop(
|
|
||||||
listener: TcpListener,
|
|
||||||
termination: impl Future,
|
|
||||||
registry: MetricsRegistry,
|
|
||||||
rooms: RoomRegistry,
|
|
||||||
players: PlayerRegistry,
|
|
||||||
) -> Result<()> {
|
|
||||||
log::info!("Starting the http server");
|
|
||||||
pin!(termination);
|
|
||||||
let reqs = IntGauge::with_opts(Opts::new("sockets", "Number of open sockets"))?;
|
|
||||||
registry.register(Box::new(reqs.clone()))?;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
select! {
|
|
||||||
_ = &mut termination => {
|
|
||||||
log::info!("Terminating the http server");
|
|
||||||
return Ok(())
|
|
||||||
},
|
|
||||||
result = listener.accept() => {
|
|
||||||
let (stream, _) = result?;
|
|
||||||
let registry = registry.clone();
|
|
||||||
let players = players.clone();
|
|
||||||
let reqs = reqs.clone();
|
|
||||||
tokio::task::spawn(async move {
|
|
||||||
reqs.inc();
|
|
||||||
let registry = registry.clone();
|
|
||||||
if let Err(err) = http1::Builder::new()
|
|
||||||
.serve_connection(stream, service_fn(move |r| route(registry.clone(), players.clone(), r)))
|
|
||||||
.with_upgrades()
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
tracing::error!("Error serving connection: {:?}", err);
|
|
||||||
}
|
|
||||||
reqs.dec();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
110
src/main.rs
110
src/main.rs
|
@ -1,38 +1,24 @@
|
||||||
mod core;
|
mod core;
|
||||||
mod http;
|
|
||||||
mod prelude;
|
mod prelude;
|
||||||
mod projections;
|
mod projections;
|
||||||
mod protos;
|
mod protos;
|
||||||
mod tcp;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
use figment::providers::Format;
|
||||||
|
use figment::{providers::Toml, Figment};
|
||||||
|
use prometheus::Registry as MetricsRegistry;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::core::player::PlayerRegistry;
|
use crate::core::player::PlayerRegistry;
|
||||||
use crate::core::room::RoomRegistry;
|
use crate::core::room::RoomRegistry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use prometheus::{IntCounter, Opts, Registry};
|
|
||||||
use tcp::ClientSocketActor;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::future::Future;
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use figment::providers::Format;
|
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
|
||||||
|
|
||||||
use figment::{providers::Toml, Figment};
|
|
||||||
use serde::Deserialize;
|
|
||||||
use tokio::io::BufWriter;
|
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct ServerConfig {
|
struct ServerConfig {
|
||||||
cluster: ClusterConfig,
|
telemetry: util::telemetry::ServerConfig,
|
||||||
}
|
irc: projections::irc::ServerConfig,
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
|
||||||
struct ClusterConfig {
|
|
||||||
name: String,
|
|
||||||
servers: Vec<SocketAddr>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_config() -> Result<ServerConfig> {
|
fn load_config() -> Result<ServerConfig> {
|
||||||
|
@ -46,37 +32,21 @@ async fn main() -> Result<()> {
|
||||||
set_up_logging()?;
|
set_up_logging()?;
|
||||||
let sleep = ctrl_c()?;
|
let sleep = ctrl_c()?;
|
||||||
let config = load_config()?;
|
let config = load_config()?;
|
||||||
dbg!(config);
|
|
||||||
tracing::info!("Booting up");
|
|
||||||
let registry = Registry::new();
|
|
||||||
let counter = IntCounter::with_opts(Opts::new("actor_count", "Number of alive actors"))?;
|
|
||||||
registry.register(Box::new(counter.clone()))?;
|
|
||||||
|
|
||||||
|
tracing::info!("Booting up");
|
||||||
|
tracing::info!("Loaded config: {config:?}");
|
||||||
|
let registry = MetricsRegistry::new();
|
||||||
let rooms = RoomRegistry::empty();
|
let rooms = RoomRegistry::empty();
|
||||||
let players = PlayerRegistry::empty(rooms.clone());
|
let players = PlayerRegistry::empty(rooms.clone());
|
||||||
|
let telemetry_terminator = util::telemetry::launch(&config.telemetry, registry.clone()).await?;
|
||||||
let listener = TcpListener::bind("127.0.0.1:3721").await?;
|
let irc = projections::irc::launch(&config.irc, players).await?;
|
||||||
let listener_http = TcpListener::bind("127.0.0.1:8080").await?;
|
|
||||||
let http_server_actor = http::HttpServerActor::launch(
|
|
||||||
listener_http,
|
|
||||||
registry.clone(),
|
|
||||||
rooms.clone(),
|
|
||||||
players.clone(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let irc_config = projections::irc::ServerConfig {
|
|
||||||
listen_on: "127.0.0.1:6667".parse()?,
|
|
||||||
};
|
|
||||||
let irc = projections::irc::launch(irc_config, players).await?;
|
|
||||||
|
|
||||||
tracing::info!("Started");
|
tracing::info!("Started");
|
||||||
|
|
||||||
run(listener, sleep).await?;
|
sleep.await;
|
||||||
|
|
||||||
// sleep.await;
|
|
||||||
tracing::info!("Begin shutdown");
|
tracing::info!("Begin shutdown");
|
||||||
irc.terminate().await?;
|
irc.terminate().await?;
|
||||||
http_server_actor.terminate().await?;
|
telemetry_terminator.terminate().await?;
|
||||||
tracing::info!("Shutdown complete");
|
tracing::info!("Shutdown complete");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -94,51 +64,3 @@ fn set_up_logging() -> Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(listener: TcpListener, shutdown: impl Future<Output = ()>) -> Result<()> {
|
|
||||||
tokio::pin!(shutdown);
|
|
||||||
|
|
||||||
let mut counter: u32 = 0;
|
|
||||||
let mut conns: HashMap<u32, _> = HashMap::new();
|
|
||||||
|
|
||||||
let (sender, mut chan) = tokio::sync::mpsc::channel(32);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let accept = listener.accept();
|
|
||||||
tokio::select! {
|
|
||||||
id = chan.recv() => {
|
|
||||||
match id {
|
|
||||||
Some(id) => {
|
|
||||||
conns.remove(&id);
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
result = accept => {
|
|
||||||
let (connect, address) = result?;
|
|
||||||
let id = counter;
|
|
||||||
counter += 1;
|
|
||||||
let fiber = handle_connection(connect, address, id, sender.clone()).await?;
|
|
||||||
conns.insert(id, fiber);
|
|
||||||
},
|
|
||||||
_ = &mut shutdown => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (_, i) in conns {
|
|
||||||
dbg!(i.terminate().await?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_connection(
|
|
||||||
connect: TcpStream,
|
|
||||||
address: SocketAddr,
|
|
||||||
id: u32,
|
|
||||||
updater: Sender<u32>,
|
|
||||||
) -> Result<ClientSocketActor> {
|
|
||||||
tracing::info!("Incoming socket #{} from {}", id, address);
|
|
||||||
let writer = BufWriter::new(connect);
|
|
||||||
Ok(ClientSocketActor::launch(writer, updater, id)?)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub use std::future::Future;
|
||||||
|
|
||||||
pub use tokio::pin;
|
pub use tokio::pin;
|
||||||
pub use tokio::select;
|
pub use tokio::select;
|
||||||
pub use tokio::task::JoinHandle;
|
pub use tokio::task::JoinHandle;
|
||||||
|
@ -7,9 +9,3 @@ pub mod log {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, anyhow::Error>;
|
pub type Result<T> = std::result::Result<T, anyhow::Error>;
|
||||||
|
|
||||||
pub fn failure(explain: &str) -> Result<()> {
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use std::future::Future;
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter};
|
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter};
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
use tokio::sync::oneshot::channel;
|
use tokio::sync::oneshot::channel;
|
||||||
|
@ -9,6 +10,7 @@ use crate::prelude::*;
|
||||||
use crate::protos::irc::*;
|
use crate::protos::irc::*;
|
||||||
use crate::util::Terminator;
|
use crate::util::Terminator;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
pub listen_on: SocketAddr,
|
pub listen_on: SocketAddr,
|
||||||
}
|
}
|
||||||
|
@ -53,7 +55,7 @@ async fn handle_socket(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn launch(config: ServerConfig, players: PlayerRegistry) -> Result<Terminator> {
|
pub async fn launch(config: &ServerConfig, players: PlayerRegistry) -> Result<Terminator> {
|
||||||
log::info!("Starting IRC projection");
|
log::info!("Starting IRC projection");
|
||||||
let (signal, mut rx) = channel();
|
let (signal, mut rx) = channel();
|
||||||
let listener = TcpListener::bind(config.listen_on).await?;
|
let listener = TcpListener::bind(config.listen_on).await?;
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
use tokio::{
|
|
||||||
io::{AsyncWriteExt, BufWriter},
|
|
||||||
net::TcpStream,
|
|
||||||
sync::mpsc::{Receiver, Sender},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ClientSocketActor {
|
|
||||||
sender: Sender<ClientSocketActorMessage>,
|
|
||||||
fiber: JoinHandle<Result<ClientSocketActorTermination>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum ClientSocketActorMessage {
|
|
||||||
Terminate,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum ClientSocketActorTermination {
|
|
||||||
ServerClosed,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientSocketActor {
|
|
||||||
pub async fn terminate(self) -> Result<()> {
|
|
||||||
self.sender
|
|
||||||
.send(ClientSocketActorMessage::Terminate)
|
|
||||||
.await?;
|
|
||||||
self.fiber.await??;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn launch(
|
|
||||||
writer: BufWriter<TcpStream>,
|
|
||||||
updater: Sender<u32>,
|
|
||||||
id: u32,
|
|
||||||
) -> Result<ClientSocketActor> {
|
|
||||||
let (sender, chan) = tokio::sync::mpsc::channel(32);
|
|
||||||
let fiber: JoinHandle<Result<ClientSocketActorTermination>> =
|
|
||||||
tokio::spawn(ClientSocketActor::handle_connect(writer, chan, updater, id));
|
|
||||||
Ok(ClientSocketActor { sender, fiber })
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_connect(
|
|
||||||
mut writer: BufWriter<TcpStream>,
|
|
||||||
mut messagebox: Receiver<ClientSocketActorMessage>,
|
|
||||||
updater: Sender<u32>,
|
|
||||||
id: u32,
|
|
||||||
) -> Result<ClientSocketActorTermination> {
|
|
||||||
async fn handle(
|
|
||||||
messagebox: &mut Receiver<ClientSocketActorMessage>,
|
|
||||||
writer: &mut BufWriter<TcpStream>,
|
|
||||||
) -> Result<Option<ClientSocketActorTermination>> {
|
|
||||||
writer.write_all("privet\n".as_bytes()).await?;
|
|
||||||
writer.flush().await?;
|
|
||||||
tracing::info!("Wrote");
|
|
||||||
tokio::select! {
|
|
||||||
_ = messagebox.recv() => return Ok(Some(ClientSocketActorTermination::ServerClosed)),
|
|
||||||
_ = tokio::time::sleep(Duration::from_millis(200)) => (),
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match handle(&mut messagebox, &mut writer).await {
|
|
||||||
Ok(None) => {}
|
|
||||||
Ok(Some(termination)) => return Ok(termination),
|
|
||||||
Err(err) => {
|
|
||||||
tracing::error!("{}", err);
|
|
||||||
updater.send(id).await?;
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
mod client;
|
|
||||||
|
|
||||||
pub use client::ClientSocketActor;
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use http_body_util::Full;
|
||||||
|
use hyper::{body::Bytes, Response, StatusCode};
|
||||||
|
|
||||||
|
pub fn not_found() -> std::result::Result<Response<Full<Bytes>>, Infallible> {
|
||||||
|
let mut response = Response::new(Full::new(Bytes::from("404")));
|
||||||
|
*response.status_mut() = StatusCode::NOT_FOUND;
|
||||||
|
Ok(response)
|
||||||
|
}
|
|
@ -3,7 +3,9 @@ use tokio::sync::oneshot::{channel, Sender};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub mod http;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
pub mod telemetry;
|
||||||
|
|
||||||
pub struct Terminator {
|
pub struct Terminator {
|
||||||
signal: Sender<()>,
|
signal: Sender<()>,
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
use std::convert::Infallible;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use futures_util::FutureExt;
|
||||||
|
use http_body_util::{BodyExt, Full};
|
||||||
|
use hyper::body::Bytes;
|
||||||
|
use hyper::server::conn::http1;
|
||||||
|
use hyper::service::service_fn;
|
||||||
|
use hyper::{Method, Request, Response};
|
||||||
|
use prometheus::{Encoder, Registry as MetricsRegistry, TextEncoder};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
use tokio::sync::oneshot::channel;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use crate::util::http::*;
|
||||||
|
use crate::util::Terminator;
|
||||||
|
|
||||||
|
type BoxBody = http_body_util::combinators::BoxBody<Bytes, Infallible>;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct ServerConfig {
|
||||||
|
pub listen_on: SocketAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn launch(config: &ServerConfig, metrics: MetricsRegistry) -> Result<Terminator> {
|
||||||
|
log::info!("Starting the telemetry service");
|
||||||
|
let listener = TcpListener::bind(config.listen_on).await?;
|
||||||
|
log::debug!("Listener started");
|
||||||
|
let (signal, rx) = channel();
|
||||||
|
let handle = tokio::task::spawn(main_loop(listener, metrics, rx.map(|_| ())));
|
||||||
|
let terminator = Terminator::from_raw(signal, handle);
|
||||||
|
Ok(terminator)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn main_loop(
|
||||||
|
listener: TcpListener,
|
||||||
|
metrics: MetricsRegistry,
|
||||||
|
termination: impl Future<Output = ()>,
|
||||||
|
) -> Result<()> {
|
||||||
|
pin!(termination);
|
||||||
|
loop {
|
||||||
|
select! {
|
||||||
|
biased;
|
||||||
|
_ = &mut termination => break,
|
||||||
|
result = listener.accept() => {
|
||||||
|
let (stream, _) = result?;
|
||||||
|
let metrics = metrics.clone();
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
let registry = metrics.clone();
|
||||||
|
let server = http1::Builder::new().serve_connection(stream, service_fn(move |r| route(registry.clone(), r)));
|
||||||
|
if let Err(err) = server.await {
|
||||||
|
tracing::error!("Error serving connection: {:?}", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log::info!("Terminating the telemetry service");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn route(
|
||||||
|
registry: MetricsRegistry,
|
||||||
|
request: Request<hyper::body::Incoming>,
|
||||||
|
) -> std::result::Result<Response<BoxBody>, Infallible> {
|
||||||
|
match (request.method(), request.uri().path()) {
|
||||||
|
(&Method::GET, "/metrics") => Ok(metrics(registry)?.map(BodyExt::boxed)),
|
||||||
|
_ => Ok(not_found()?.map(BodyExt::boxed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metrics(registry: MetricsRegistry) -> std::result::Result<Response<Full<Bytes>>, Infallible> {
|
||||||
|
let mf = registry.gather();
|
||||||
|
let mut buffer = vec![];
|
||||||
|
TextEncoder
|
||||||
|
.encode(&mf, &mut buffer)
|
||||||
|
.expect("write to vec cannot fail");
|
||||||
|
Ok(Response::new(Full::new(Bytes::from(buffer))))
|
||||||
|
}
|
Loading…
Reference in New Issue