#![forbid(unsafe_code)]
use crate::errors::Error;
use actix_web::{
http,
server,
};
use actix_web::middleware::Logger;
use log::{
debug,
info,
};
mod handlers;
use handlers::{
index,
metrics,
};
mod templates;
use templates::render_index_page;
pub(self) struct AppState {
exporter: jail_exporter::Exporter,
index_page: String,
}
#[derive(Debug)]
pub struct Server {
bind_address: String,
telemetry_path: String,
}
impl Default for Server {
fn default() -> Self {
Self {
bind_address: "127.0.0.1:9452".into(),
telemetry_path: "/metrics".into(),
}
}
}
impl Server {
pub fn new() -> Self {
Default::default()
}
pub fn bind_address(mut self, bind_address: String) -> Self {
debug!("Setting server bind_address to: {}", bind_address);
self.bind_address = bind_address;
self
}
pub fn telemetry_path(mut self, telemetry_path: String) -> Self {
debug!("Setting server telemetry_path to: {}", telemetry_path);
self.telemetry_path = telemetry_path;
self
}
pub fn run(self) -> Result<(), Error> {
let bind_address = self.bind_address;
let exporter = jail_exporter::Exporter::new();
let index_page = render_index_page(&self.telemetry_path)?;
let telemetry_path = self.telemetry_path.clone();
debug!("Registering HTTP app routes");
let app = move || {
let state = AppState {
exporter: exporter.clone(),
index_page: index_page.clone(),
};
actix_web::App::with_state(state)
.middleware(Logger::default())
.resource("/", |r| r.method(http::Method::GET).f(index))
.resource(&telemetry_path, |r| {
r.method(http::Method::GET).f(metrics)
})
};
debug!("Attempting to bind to: {}", bind_address);
let server = match server::new(app).bind(&bind_address) {
Ok(s) => Ok(s),
Err(e) => {
Err(Error::BindAddress(format!("{}: {}", bind_address, e)))
},
}?;
info!("Starting HTTP server on {}", bind_address);
server.run();
Ok(())
}
}