aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbreezystatic772025-06-01 10:40:43 -0400
committerbreezystatic772025-06-01 10:40:43 -0400
commit092092ede52afa1faaca8b359d8b5d4514709389 (patch)
treecdc1645c80cd93f9886c395280bf7f0c976ba059
parentff4ef3ced0ff2ca7bc2136e43a351fac96eab7df (diff)
switch logging to aggregate waste calc
Diffstat (limited to '')
-rw-r--r--Cargo.lock53
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs62
3 files changed, 109 insertions, 7 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f0da0cd..79d9ad3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -174,6 +174,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
+name = "deranged"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -465,6 +474,12 @@ dependencies = [
]
[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -543,12 +558,19 @@ dependencies = [
"rand_pcg",
"rand_seeder",
"thousands",
+ "time",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -785,6 +807,37 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.3.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
+dependencies = [
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
+
+[[package]]
+name = "time-macros"
+version = "0.2.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
name = "tokio"
version = "1.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index bb152e5..b5ae7eb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ rand = "0.8.5"
rand_pcg = "0.3.1"
rand_seeder = "0.3.0"
thousands = "0.2.0"
+time = { version = "0.3.41", features = ["formatting"] }
tokio = { version = "1.43.0", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
diff --git a/src/main.rs b/src/main.rs
index 352315b..705bd07 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,8 @@ use std::ops::RangeInclusive;
use std::pin::Pin;
use std::process::ExitCode;
use std::sync::Arc;
+use time::format_description::well_known::Iso8601;
+use time::UtcDateTime;
use clap::Parser;
use http_body_util::Full;
@@ -20,6 +22,7 @@ use rand::prelude::*;
use rand_pcg::Pcg64;
use rand_seeder::Seeder;
use tokio::net::TcpListener;
+use tokio::sync::Mutex;
use tracing::level_filters::LevelFilter;
use tracing_subscriber::EnvFilter;
@@ -55,6 +58,9 @@ struct Args {
links_max: u16,
#[arg(long)]
href_prefix: Option<String>,
+ /// tiem in seconds between reporting wasted resources
+ #[arg(long, default_value_t = 3600)]
+ waste_log: u64,
}
#[tokio::main]
@@ -71,7 +77,36 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error + Send + Sync>> {
)
.init();
- let generator = PageGenerator::new(&args);
+ let stats = Arc::new(Mutex::new(StatsReport {
+ seconds_wasted: 0.0,
+ bytes_wasted: 0,
+ period_start: UtcDateTime::now(),
+ }));
+
+ {
+ let stats = stats.clone();
+ let waste_log = args.waste_log;
+ tokio::task::spawn(async move {
+ let mut interval =
+ tokio::time::interval(std::time::Duration::from_secs(waste_log));
+ loop {
+ interval.tick().await;
+ let mut stats = stats.lock().await;
+ let new_period = UtcDateTime::now();
+ tracing::info!(
+ seconds_wasted = stats.seconds_wasted,
+ bytes_wasted = stats.bytes_wasted,
+ period_start = stats.period_start.format(&Iso8601::DEFAULT).unwrap(),
+ period_end = new_period.format(&Iso8601::DEFAULT).unwrap(),
+ );
+ stats.seconds_wasted = 0.0;
+ stats.bytes_wasted = 0;
+ stats.period_start = new_period;
+ }
+ });
+ }
+
+ let generator = PageGenerator::new(&args, stats.clone());
generator.stats();
@@ -100,7 +135,7 @@ async fn main() -> Result<ExitCode, Box<dyn std::error::Error + Send + Sync>> {
}
}
-#[derive(Debug, Clone)]
+#[derive(Clone)]
struct RandomPageService {
pub ctx: Arc<PageGenerator>,
}
@@ -136,7 +171,6 @@ impl Service<Request<hyper::body::Incoming>> for RandomPageService {
}
}
-#[derive(Debug)]
struct PageGenerator {
seed: String,
segments: u8,
@@ -144,12 +178,13 @@ struct PageGenerator {
paragraph_size: RangeInclusive<u16>,
n_links: RangeInclusive<u16>,
delay: RangeInclusive<u64>,
+ stats: Arc<Mutex<StatsReport>>,
dict: Vec<&'static str>,
dict_set: HashSet<&'static str>,
}
impl PageGenerator {
- fn new(args: &Args) -> Self {
+ fn new(args: &Args, stats: Arc<Mutex<StatsReport>>) -> Self {
let dictionary_data = include_bytes!(env!("DICTIONARY_FILE_PATH"));
let dictionary_string: &'static str =
std::str::from_utf8(dictionary_data).unwrap();
@@ -161,6 +196,7 @@ impl PageGenerator {
..=(args.paragraph_max.max(args.paragraph_min)),
n_links: (args.links_min)..=(args.links_max.max(args.links_min)),
delay: args.delay_min..=(args.delay_max.max(args.delay_min)),
+ stats,
dict: dictionary_string.split_whitespace().collect(),
dict_set: dictionary_string.split_whitespace().collect(),
}
@@ -242,9 +278,9 @@ impl PageGenerator {
.collect::<Vec<String>>()
.join("");
- tracing::info!(route, delay);
+ tracing::debug!(route, delay);
- Ok(format!(
+ let body = format!(
"<!DOCTYPE html>\
<html>\
<head>\
@@ -258,7 +294,13 @@ impl PageGenerator {
{random_links}\
</body>\
</html>",
- ))
+ );
+ {
+ let mut stats = self.stats.lock().await;
+ stats.seconds_wasted += delay.unwrap_or_default() as f64 / 1000.0;
+ stats.bytes_wasted += body.len() as u128;
+ }
+ Ok(body)
}
fn random_route_link(&self, rng: &mut Pcg64) -> String {
let n_segments = rng.gen_range(1..=self.segments);
@@ -276,6 +318,12 @@ impl PageGenerator {
}
}
+struct StatsReport {
+ seconds_wasted: f64,
+ bytes_wasted: u128,
+ period_start: UtcDateTime,
+}
+
pub fn build_dict() -> Vec<&'static str> {
let dictionary_data = include_bytes!(env!("DICTIONARY_FILE_PATH"));
let dictionary_string: &'static str =