Add metrics

Change dashboards to load an index.html file compiled otherwise
This commit is contained in:
jude
2023-10-29 18:00:45 +00:00
committed by jude
parent 1d64c8bb79
commit 5d3b77f1cd
10 changed files with 130 additions and 16 deletions

View File

@ -19,3 +19,4 @@ lazy_static = "1.4.0"
rand = "0.8"
base64 = "0.13"
csv = "1.2"
prometheus = "0.13.3"

View File

@ -6,6 +6,7 @@ mod consts;
mod macros;
mod catchers;
mod guards;
mod metrics;
mod routes;
use std::{env, path::Path};
@ -25,7 +26,10 @@ use serenity::{
};
use sqlx::{MySql, Pool};
use crate::consts::{CNC_GUILD, DISCORD_OAUTH_AUTHORIZE, DISCORD_OAUTH_TOKEN, SUBSCRIPTION_ROLES};
use crate::{
consts::{CNC_GUILD, DISCORD_OAUTH_AUTHORIZE, DISCORD_OAUTH_TOKEN, SUBSCRIPTION_ROLES},
metrics::{init_metrics, MetricProducer},
};
type Database = MySql;
@ -64,7 +68,10 @@ pub async fn initialize(
let static_path =
if Path::new("web/static").exists() { "web/static" } else { "/lib/reminder-rs/static" };
init_metrics();
rocket::build()
.attach(MetricProducer)
.attach(Template::fairing())
.register(
"/",
@ -85,12 +92,13 @@ pub async fn initialize(
.mount(
"/",
routes![
routes::index,
routes::cookies,
routes::index,
routes::metrics::metrics,
routes::privacy,
routes::terms,
routes::return_to_same_site,
routes::report::report_error,
routes::return_to_same_site,
routes::terms,
],
)
.mount(

43
web/src/metrics.rs Normal file
View File

@ -0,0 +1,43 @@
use lazy_static::lazy_static;
use prometheus::{IntCounterVec, Opts, Registry};
use rocket::{
fairing::{Fairing, Info, Kind},
Data, Request, Response,
};
lazy_static! {
pub static ref REGISTRY: Registry = Registry::new();
static ref REQUEST_COUNTER: IntCounterVec =
IntCounterVec::new(Opts::new("requests", "Requests"), &["method", "route"]).unwrap();
static ref RESPONSE_COUNTER: IntCounterVec =
IntCounterVec::new(Opts::new("responses", "Responses"), &["status", "route"]).unwrap();
}
pub fn init_metrics() {
REGISTRY.register(Box::new(REQUEST_COUNTER.clone())).unwrap();
}
pub struct MetricProducer;
#[rocket::async_trait]
impl Fairing for MetricProducer {
fn info(&self) -> Info {
Info { name: "Metrics fairing", kind: Kind::Request }
}
async fn on_request(&self, req: &mut Request<'_>, _data: &mut Data<'_>) {
if let Some(route) = req.route() {
REQUEST_COUNTER
.with_label_values(&[req.method().as_str(), &route.uri.to_string()])
.inc();
}
}
async fn on_response<'r>(&self, req: &'r Request<'_>, resp: &mut Response<'r>) {
if let Some(route) = req.route() {
RESPONSE_COUNTER
.with_label_values(&[&resp.status().code.to_string(), &route.uri.to_string()])
.inc();
}
}
}

View File

@ -1 +0,0 @@

View File

@ -1,8 +1,13 @@
use std::collections::HashMap;
use std::path::Path;
use chrono::{naive::NaiveDateTime, Utc};
use rand::{rngs::OsRng, seq::IteratorRandom};
use rocket::{http::CookieJar, response::Redirect, serde::json::json};
use rocket::{
fs::{relative, NamedFile},
http::CookieJar,
response::Redirect,
serde::json::json,
};
use rocket_dyn_templates::Template;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serenity::{
@ -27,7 +32,6 @@ use crate::{
pub mod api;
pub mod export;
pub mod guild;
type Unset<T> = Option<T>;
@ -655,22 +659,26 @@ async fn create_database_channel(
}
#[get("/")]
pub async fn dashboard_home(cookies: &CookieJar<'_>) -> Result<Template, Redirect> {
pub async fn dashboard_home(cookies: &CookieJar<'_>) -> Result<NamedFile, Redirect> {
if cookies.get_private("userid").is_some() {
let mut map = HashMap::new();
map.insert("version", env!("CARGO_PKG_VERSION"));
Ok(Template::render("dashboard", &map))
NamedFile::open(Path::new(relative!("static/index.html"))).await.map_err(|e| {
warn!("Couldn't render dashboard: {:?}", e);
Redirect::to("/login/discord")
})
} else {
Err(Redirect::to("/login/discord"))
}
}
#[get("/<_..>")]
pub async fn dashboard(cookies: &CookieJar<'_>) -> Result<Template, Redirect> {
pub async fn dashboard(cookies: &CookieJar<'_>) -> Result<NamedFile, Redirect> {
if cookies.get_private("userid").is_some() {
let mut map = HashMap::new();
map.insert("version", env!("CARGO_PKG_VERSION"));
Ok(Template::render("dashboard", &map))
NamedFile::open(Path::new(relative!("static/index.html"))).await.map_err(|e| {
warn!("Couldn't render dashboard: {:?}", e);
Redirect::to("/login/discord")
})
} else {
Err(Redirect::to("/login/discord"))
}

18
web/src/routes/metrics.rs Normal file
View File

@ -0,0 +1,18 @@
use prometheus;
use crate::metrics::REGISTRY;
#[get("/metrics")]
pub async fn metrics() -> String {
let encoder = prometheus::TextEncoder::new();
let res_custom = encoder.encode_to_string(&REGISTRY.gather());
match res_custom {
Ok(s) => s,
Err(e) => {
warn!("Error encoding metrics: {:?}", e);
String::new()
}
}
}

View File

@ -1,6 +1,7 @@
pub mod admin;
pub mod dashboard;
pub mod login;
pub mod metrics;
pub mod report;
use std::collections::HashMap;

View File

@ -633,6 +633,10 @@ li.highlight {
display: flex;
}
.button-row-edit > button {
margin-right: 4px;
}
.button-row .button-row-reminder {
flex-grow: 0;
padding: 2px;