reorganize stats collector

This commit is contained in:
yggverse 2025-06-28 17:38:17 +03:00
parent d82f09d659
commit 450bbe60f3
5 changed files with 38 additions and 31 deletions

View file

@ -32,7 +32,6 @@ impl Connection {
} }
pub fn handle(mut self) { pub fn handle(mut self) {
self.session.stats.connections.add(&self.address.client);
let mut t = 0; // total bytes let mut t = 0; // total bytes
match self.request() { match self.request() {
Ok(q) => { Ok(q) => {
@ -40,6 +39,7 @@ impl Connection {
"[{}] < [{}] request `{q}`...", "[{}] < [{}] request `{q}`...",
self.address.server, self.address.client self.address.server, self.address.client
)); ));
self.session.request.add(&self.address.client, &q);
self.session self.session
.clone() .clone()
.public .public
@ -74,8 +74,8 @@ impl Connection {
&if is_root { &if is_root {
self.session.template.welcome( self.session.template.welcome(
Some(s), Some(s),
Some(self.session.stats.connections.count()), Some(self.session.request.count()),
Some(self.session.stats.connections.total()), Some(self.session.request.total()),
) )
} else { } else {
self.session.template.index(Some(s)) self.session.template.index(Some(s))

View file

@ -1,17 +1,17 @@
mod access_log; mod access_log;
mod debug; mod debug;
mod public; mod public;
mod stats; mod request;
mod template; mod template;
use {access_log::AccessLog, debug::Debug, public::Public, stats::Stats, template::Template}; use {access_log::AccessLog, debug::Debug, public::Public, request::Request, template::Template};
/// Shared, multi-thread features for the current server session /// Shared, multi-thread features for the current server session
pub struct Session { pub struct Session {
pub access_log: AccessLog, pub access_log: AccessLog,
pub debug: Debug, pub debug: Debug,
pub stats: Stats,
pub public: Public, pub public: Public,
pub request: Request,
pub template: Template, pub template: Template,
} }
@ -21,11 +21,11 @@ impl Session {
Ok(Self { Ok(Self {
access_log: AccessLog::init(config)?, access_log: AccessLog::init(config)?,
debug: Debug::init(config)?, debug: Debug::init(config)?,
stats: Stats::init( public: Public::init(config)?,
request: Request::init(
// do not init `Connection` event if its features not in use // do not init `Connection` event if its features not in use
template.welcome.contains("{hosts}") || template.welcome.contains("{hits}"), template.welcome.contains("{hosts}") || template.welcome.contains("{hits}"),
)?, ),
public: Public::init(config)?,
template, template,
}) })
} }

View file

@ -1,13 +1,16 @@
mod query;
use query::Query;
use std::{ use std::{
collections::HashMap, collections::HashMap,
net::{IpAddr, SocketAddr}, net::{IpAddr, SocketAddr},
sync::RwLock, sync::RwLock,
}; };
/// Count peer connections (for the current server session) /// Collect peer requests to print stats and visitors count
pub struct Connections(Option<RwLock<HashMap<IpAddr, usize>>>); pub struct Request(Option<RwLock<HashMap<IpAddr, Vec<Query>>>>);
impl Connections { impl Request {
pub fn init(is_enabled: bool) -> Self { pub fn init(is_enabled: bool) -> Self {
if is_enabled { if is_enabled {
Self(Some(RwLock::new(HashMap::with_capacity(100)))) Self(Some(RwLock::new(HashMap::with_capacity(100))))
@ -16,13 +19,13 @@ impl Connections {
} }
} }
pub fn add(&self, peer: &SocketAddr) { pub fn add(&self, peer: &SocketAddr, query: &str) {
if let Some(ref this) = self.0 { if let Some(ref this) = self.0 {
this.write() this.write()
.unwrap() .unwrap()
.entry(peer.ip()) .entry(peer.ip())
.and_modify(|c| *c += 1) .and_modify(|c| c.push(Query::new(query)))
.or_insert(1); .or_insert(vec![Query::new(query)]);
} }
} }
@ -36,7 +39,11 @@ impl Connections {
pub fn total(&self) -> usize { pub fn total(&self) -> usize {
if let Some(ref this) = self.0 { if let Some(ref this) = self.0 {
this.read().unwrap().values().sum() let mut t = 0;
for c in this.read().unwrap().values() {
t += c.len()
}
t
} else { } else {
0 0
} }

View file

@ -0,0 +1,15 @@
use std::time::SystemTime;
pub struct Query {
pub time: SystemTime,
pub value: String,
}
impl Query {
pub fn new(value: &str) -> Self {
Self {
time: SystemTime::now(),
value: value.to_string(),
}
}
}

View file

@ -1,15 +0,0 @@
mod connections;
use connections::Connections;
pub struct Stats {
pub connections: Connections,
// another features...
}
impl Stats {
pub fn init(is_connection_enabled: bool) -> anyhow::Result<Self> {
Ok(Self {
connections: Connections::init(is_connection_enabled),
})
}
}