diff --git a/Cargo.lock b/Cargo.lock index 1ff565e..5e7eb2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1050,6 +1050,7 @@ dependencies = [ "julianday", "lox-library", "lox_utils", + "prometheus", "rand 0.8.5", "rdsys_backend", "reqwest", diff --git a/crates/lox-distributor/Cargo.toml b/crates/lox-distributor/Cargo.toml index 1f07a4c..ea017e0 100644 --- a/crates/lox-distributor/Cargo.toml +++ b/crates/lox-distributor/Cargo.toml @@ -28,6 +28,7 @@ lox_utils = { path = "../lox-utils", version = "0.1.0"} rdsys_backend = { path = "../rdsys-backend-api", version = "0.2"} clap = { version = "4.4.7", features = ["derive"] } serde_json = "1.0.108" +prometheus = "0.13.3" sled = "0.34.7" [dependencies.chrono] diff --git a/crates/lox-distributor/src/db_handler.rs b/crates/lox-distributor/src/db_handler.rs index d7a9bf4..f14ded6 100644 --- a/crates/lox-distributor/src/db_handler.rs +++ b/crates/lox-distributor/src/db_handler.rs @@ -1,5 +1,6 @@ use std::sync::{Arc, Mutex}; +use crate::metrics::Metrics; use crate::{lox_context, DbConfig}; use chrono::{naive::Days, DateTime, Local, NaiveDateTime, Utc}; use lox_library::{BridgeAuth, BridgeDb}; @@ -31,12 +32,13 @@ impl DB { db_config: DbConfig, roll_back_date: Option, ) -> Result<(DB, lox_context::LoxServerContext), sled::Error> { - let context: lox_context::LoxServerContext; + let mut context: lox_context::LoxServerContext; let (lox_db, context) = match sled::open(db_config.db_path) { Ok(lox_db) => { // Check if the lox_db already exists if lox_db.was_recovered() { context = read_lox_context_from_db(lox_db.clone(), roll_back_date); + context.metrics = Metrics::default(); //Otherwise, create a new Lox context } else { let new_db = BridgeDb::new(); @@ -46,6 +48,7 @@ impl DB { ba: Arc::new(Mutex::new(new_ba)), extra_bridges: Arc::new(Mutex::new(Vec::new())), to_be_replaced_bridges: Arc::new(Mutex::new(Vec::new())), + metrics: Metrics::default(), }; } (DB { db: lox_db }, context) @@ -123,13 +126,12 @@ fn use_last_context(lox_db: sled::Db) -> lox_context::LoxServerContext { #[cfg(test)] mod tests { use super::lox_context::LoxServerContext; - use super::DbConfig; use super::DB; + use super::DbConfig; #[test] fn test_write_context() { - let (mut lox_db, _context) = - DB::open_new_or_existing_db(DbConfig::default(), None).unwrap(); + let (mut lox_db, _context) = DB::open_new_or_existing_db(DbConfig::default(), None).unwrap(); assert!( lox_db.db.is_empty(), "db read from context that shouldn't exist" diff --git a/crates/lox-distributor/src/lox_context.rs b/crates/lox-distributor/src/lox_context.rs index 76e139a..da77437 100644 --- a/crates/lox-distributor/src/lox_context.rs +++ b/crates/lox-distributor/src/lox_context.rs @@ -6,7 +6,7 @@ use lox_library::{ blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite, redeem_invite, trust_promotion, }, - BridgeAuth, BridgeDb, ExceededMaxBridgesError, IssuerPubKey, + BridgeAuth, BridgeDb, ExceededMaxBridgesError, IssuerPubKey, MAX_DAILY_BRIDGES, }; use rdsys_backend::proto::{Resource, ResourceState}; use serde::{Deserialize, Serialize}; @@ -19,6 +19,7 @@ use std::{ use zkp::ProofError; use crate::resource_parser::{parse_into_bridgelines, sort_for_parsing}; +use crate::metrics::Metrics; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct LoxServerContext { @@ -26,6 +27,8 @@ pub struct LoxServerContext { pub ba: Arc>, pub extra_bridges: Arc>>, pub to_be_replaced_bridges: Arc>>, + #[serde(skip)] + pub metrics: Metrics, } impl LoxServerContext { @@ -320,7 +323,16 @@ impl LoxServerContext { fn gen_invite(&self) -> Result { let mut obj = self.db.lock().unwrap(); match obj.invite() { - Ok(invite) => Ok(lox_utils::Invite { invite }), + Ok(invite) => { + if obj.current_k == 1 { + self.metrics.k_reset_count.inc(); + } + // Count the number of total bridge requests + if obj.daily_bridges_distributed <= MAX_DAILY_BRIDGES { + self.metrics.buckets_requested_today.inc(); + } + Ok(lox_utils::Invite { invite }) + } Err(e) => Err(e), } } @@ -431,6 +443,7 @@ impl LoxServerContext { match self.open_inv(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.open_inv_count.inc(); prepare_header(response) } Err(e) => { @@ -448,6 +461,7 @@ impl LoxServerContext { match self.trust_promo(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.trust_promo_count.inc(); prepare_header(response) } Err(e) => { @@ -465,6 +479,7 @@ impl LoxServerContext { match self.trust_migration(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.trust_mig_count.inc(); prepare_header(response) } Err(e) => { @@ -482,6 +497,7 @@ impl LoxServerContext { match self.level_up(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.level_up_count.inc(); prepare_header(response) } Err(e) => { @@ -499,6 +515,7 @@ impl LoxServerContext { match self.issue_invite(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.issue_invite_count.inc(); prepare_header(response) } Err(e) => { @@ -516,6 +533,7 @@ impl LoxServerContext { match self.redeem_invite(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.redeem_invite_count.inc(); prepare_header(response) } Err(e) => { @@ -533,6 +551,7 @@ impl LoxServerContext { match self.check_blockage(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.check_blockage_count.inc(); prepare_header(response) } Err(e) => { @@ -550,6 +569,7 @@ impl LoxServerContext { match self.blockage_migration(req) { Ok(resp) => { let response = serde_json::to_string(&resp).unwrap(); + self.metrics.blockage_migration_count.inc(); prepare_header(response) } Err(e) => { diff --git a/crates/lox-distributor/src/main.rs b/crates/lox-distributor/src/main.rs index 2b36e82..ce77d90 100644 --- a/crates/lox-distributor/src/main.rs +++ b/crates/lox-distributor/src/main.rs @@ -16,6 +16,7 @@ use std::{ mod db_handler; use db_handler::DB; mod lox_context; +mod metrics; mod request_handler; use request_handler::handle; mod resource_parser; diff --git a/crates/lox-distributor/src/metrics.rs b/crates/lox-distributor/src/metrics.rs new file mode 100644 index 0000000..5fbe171 --- /dev/null +++ b/crates/lox-distributor/src/metrics.rs @@ -0,0 +1,103 @@ +use futures::executor::block_on; +use prometheus::{Counter, Encoder, Opts, Registry, TextEncoder}; + +#[derive(Debug, Clone)] +pub struct Metrics { + pub open_inv_count: Counter, + pub trust_promo_count: Counter, + pub trust_mig_count: Counter, + pub level_up_count: Counter, + pub issue_invite_count: Counter, + pub redeem_invite_count: Counter, + pub check_blockage_count: Counter, + pub blockage_migration_count: Counter, + pub k_reset_count: Counter, + pub buckets_requested_today: Counter, +} + +impl Default for Metrics { + fn default() -> Self { + // Create counters. + let open_inv_count = Counter::with_opts(Opts::new( + "open_inv_counter", + "number of open invitations distributed", + )) + .unwrap(); + let trust_promo_count = Counter::with_opts(Opts::new( + "trust_promo_counter", + "number of trust promotions requests", + )) + .unwrap(); + let trust_mig_count = Counter::with_opts(Opts::new( + "trust_mig_counter", + "number of trust migrations requests", + )) + .unwrap(); + let level_up_count = + Counter::with_opts(Opts::new("level_up_counter", "number of level up requests")) + .unwrap(); + let issue_invite_count = Counter::with_opts(Opts::new( + "issue_invite_counter", + "number of issue invite requests", + )) + .unwrap(); + let redeem_invite_count = + Counter::with_opts(Opts::new("redeem_invite_counter", "number of level up requests")) + .unwrap(); + let check_blockage_count = Counter::with_opts(Opts::new( + "check_blockage_counter", + "number of check blockage requests", + )) + .unwrap(); + let blockage_migration_count = Counter::with_opts(Opts::new( + "blockage_migration_counter", + "number of blockage migration requests", + )) + .unwrap(); + let k_reset_count = Counter::with_opts(Opts::new( + "k_reset_counter", + "number of times k has reset to 0", + )) + .unwrap(); + let buckets_requested_today = Counter::with_opts(Opts::new( + "buckets_requested_today", + "number of buckets used today", + )) + .unwrap(); + + // Create a Registry and register Counter. + let r = Registry::new(); + r.register(Box::new(open_inv_count.clone())).unwrap(); + r.register(Box::new(trust_promo_count.clone())).unwrap(); + r.register(Box::new(trust_mig_count.clone())).unwrap(); + r.register(Box::new(level_up_count.clone())).unwrap(); + r.register(Box::new(issue_invite_count.clone())).unwrap(); + r.register(Box::new(redeem_invite_count.clone())).unwrap(); + r.register(Box::new(check_blockage_count.clone())).unwrap(); + r.register(Box::new(blockage_migration_count.clone())).unwrap(); + r.register(Box::new(k_reset_count.clone())).unwrap(); + r.register(Box::new(buckets_requested_today.clone())).unwrap(); + + // Gather the metrics. + /* let mut buffer = vec![]; + let encoder = TextEncoder::new(); + let metric_families = r.gather(); + encoder.encode(&metric_families, &mut buffer).unwrap(); +*/ + + // Output to the standard output. + // println!("{}", String::from_utf8(buffer).unwrap()); + Metrics { + open_inv_count, + trust_promo_count, + trust_mig_count, + level_up_count, + issue_invite_count, + redeem_invite_count, + check_blockage_count, + blockage_migration_count, + k_reset_count, + buckets_requested_today, + } + } +} diff --git a/crates/lox-distributor/src/request_handler.rs b/crates/lox-distributor/src/request_handler.rs index 260923a..48ca6a8 100644 --- a/crates/lox-distributor/src/request_handler.rs +++ b/crates/lox-distributor/src/request_handler.rs @@ -68,6 +68,7 @@ pub async fn handle( #[cfg(test)] mod tests { use crate::lox_context; + use crate::metrics::Metrics; use super::*; @@ -230,6 +231,7 @@ mod tests { ba: Arc::new(Mutex::new(lox_auth)), extra_bridges: Arc::new(Mutex::new(Vec::new())), to_be_replaced_bridges: Arc::new(Mutex::new(Vec::new())), + metrics: Metrics::default(), }; Self { context } }