diff --git a/Cargo.lock b/Cargo.lock index 22360fd..4c0ece6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1720,6 +1720,17 @@ dependencies = [ "uom", ] +[[package]] +name = "ptth_tail" +version = "0.1.0" +dependencies = [ + "anyhow", + "reqwest", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "pulldown-cmark" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 7532e78..d67c348 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,7 @@ ptth_server = { path = "crates/ptth_server" } [workspace] -members = ["crates/*"] +members = [ + "crates/*", + "tools/*", +] diff --git a/crates/ptth_server/src/lib.rs b/crates/ptth_server/src/lib.rs index c5a89d6..7028ccd 100644 --- a/crates/ptth_server/src/lib.rs +++ b/crates/ptth_server/src/lib.rs @@ -270,9 +270,7 @@ pub async fn run_server ( } continue; }, - Ok (r) => { - r - }, + Ok (x) => x, }; if req_resp.status () == StatusCode::NO_CONTENT { diff --git a/tools/ptth_tail/Cargo.toml b/tools/ptth_tail/Cargo.toml new file mode 100644 index 0000000..8aaa59d --- /dev/null +++ b/tools/ptth_tail/Cargo.toml @@ -0,0 +1,21 @@ +[package] + +name = "ptth_tail" +version = "0.1.0" +authors = ["Trish"] +edition = "2018" +license = "AGPL-3.0" + +[dependencies] + +anyhow = "1.0.34" +tracing = "0.1.21" +tracing-subscriber = "0.2.15" + +[dependencies.reqwest] +version = "0.10.8" +features = ["stream"] + +[dependencies.tokio] +version = "0.2.22" +features = ["full"] diff --git a/tools/ptth_tail/src/main.rs b/tools/ptth_tail/src/main.rs new file mode 100644 index 0000000..7cc513b --- /dev/null +++ b/tools/ptth_tail/src/main.rs @@ -0,0 +1,80 @@ +use std::{ + convert::TryFrom, + io::{ + self, + Write, + }, + time::Duration, +}; + +use reqwest::{ + Client, + StatusCode, +}; +use tokio::{ + stream::StreamExt, + time::interval, +}; +use tracing::{ + debug, warn +}; +use tracing_subscriber::{ + EnvFilter, + fmt, + fmt::format::FmtSpan, +}; + +#[tokio::main] +async fn main () -> Result <(), anyhow::Error> { + fmt () + .with_env_filter (EnvFilter::from_default_env ()) + .with_span_events (FmtSpan::CLOSE) + .init () + ; + + let client = Client::default (); + + let server = "http://127.0.0.1:4000/files/log.txt"; + + let mut total_bytes_received = 0_u64; + let mut timer = interval (Duration::from_secs (2)); + + loop { + timer.tick ().await; + + let resp = match client + .get (server) + .header ("range", format! ("bytes={}-", total_bytes_received)) + .send ().await { + Err (e) => { + warn! ("Reqwest send error: {:?}", e); + continue; + } + Ok (x) => x, + }; + + let status = resp.status (); + + match status { + StatusCode::RANGE_NOT_SATISFIABLE => continue, + StatusCode::PARTIAL_CONTENT => (), + sc => { + debug! ("status code: {}", sc); + continue; + }, + } + + let mut stream = resp.bytes_stream (); + + while let Some (chunk) = stream.next ().await { + let chunk = match chunk { + Ok (x) => x, + Err (_) => break, + }; + io::stdout ().write_all (&chunk)?; + total_bytes_received += u64::try_from (chunk.len ())?; + } + } + + Ok (()) +}