diff --git a/rtiow/Cargo.toml b/rtiow/Cargo.toml index 7ad00c9..1a8c06c 100644 --- a/rtiow/Cargo.toml +++ b/rtiow/Cargo.toml @@ -26,6 +26,7 @@ structopt = "0.2.10" [dependencies.prometheus] features = ["process", "push"] version = "0.7.0" +optional = true [dev-dependencies] criterion = "0.2" @@ -36,3 +37,4 @@ debug = true [features] profile = ["cpuprofiler"] +prom = ["prometheus"] diff --git a/rtiow/src/bin/tracer.rs b/rtiow/src/bin/tracer.rs index dbb2009..7af52f6 100644 --- a/rtiow/src/bin/tracer.rs +++ b/rtiow/src/bin/tracer.rs @@ -10,6 +10,7 @@ extern crate structopt; #[macro_use] extern crate lazy_static; #[macro_use] +#[cfg(feature = "prom")] extern crate prometheus; use std::fs; @@ -19,6 +20,7 @@ use chrono::DateTime; use chrono::Utc; #[cfg(feature = "profile")] use cpuprofiler::PROFILER; +#[cfg(feature = "prom")] use prometheus::Encoder; use structopt::StructOpt; @@ -26,12 +28,34 @@ use rtiow::renderer::opt_hash; use rtiow::renderer::render; use rtiow::renderer::Opt; +#[cfg(feature = "prom")] lazy_static! { static ref RUNTIME_COUNTER: prometheus::Gauge = register_gauge!("render_time_seconds", "Wall clock time for render").unwrap(); } +#[cfg(not(feature = "prom"))] +fn push_metrics(_push_gateway_addr: &str, _instance: String, start_time: &DateTime) { + let runtime = *start_time - Utc::now(); + let runtime = runtime.to_std().unwrap(); + info!( + "Render time {}.{} seconds", + runtime.as_secs(), + runtime.subsec_millis() + ); +} + +#[cfg(feature = "prom")] fn push_metrics(push_gateway_addr: &str, instance: String, start_time: &DateTime) { + let runtime = start_instant.elapsed(); + info!( + "Render time {}.{} seconds", + runtime.as_secs(), + runtime.subsec_millis() + ); + + RUNTIME_COUNTER.set(runtime.as_secs() as f64 + f64::from(runtime.subsec_nanos()) * 1e-9); + let metric_families = prometheus::gather(); let encoder = prometheus::TextEncoder::new(); let stdout = std::io::stdout(); @@ -113,15 +137,6 @@ fn main() -> Result<(), std::io::Error> { info!("Saving pprof to {}", pprof_path.to_string_lossy()); PROFILER.lock().unwrap().stop().unwrap(); } - let runtime = start_instant.elapsed(); - info!( - "Render time {}.{} seconds", - runtime.as_secs(), - runtime.subsec_millis() - ); - - RUNTIME_COUNTER.set(runtime.as_secs() as f64 + f64::from(runtime.subsec_nanos()) * 1e-9); - push_metrics(&opt.push_gateway, opt_hash(&opt), &start_time); res diff --git a/rtiow/src/lib.rs b/rtiow/src/lib.rs index 2ffe432..028e30c 100644 --- a/rtiow/src/lib.rs +++ b/rtiow/src/lib.rs @@ -32,4 +32,5 @@ extern crate serde_derive; #[macro_use] extern crate lazy_static; #[macro_use] +#[cfg(feature = "prom")] extern crate prometheus; diff --git a/rtiow/src/renderer.rs b/rtiow/src/renderer.rs index 9e66553..05f8c3e 100644 --- a/rtiow/src/renderer.rs +++ b/rtiow/src/renderer.rs @@ -28,11 +28,23 @@ use crate::scenes; use crate::texture::EnvMap; use crate::vec3::Vec3; +#[cfg(feature = "prom")] lazy_static! { static ref RAY_COUNTER: prometheus::CounterVec = register_counter_vec!("rays", "Number of rays fired", &["level"]).unwrap(); } +struct MockPrometheus; +impl MockPrometheus { + fn with_label_values(&self, _: &[&str]) -> &MockPrometheus { + self + } + fn inc(&self) {} +} + +#[cfg(not(feature = "prom"))] +static RAY_COUNTER: MockPrometheus = MockPrometheus {}; + #[derive(Debug)] pub enum Model { Bench, @@ -299,7 +311,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i let scene = Arc::new(scene); let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx)); - println!("Creating {} render threads", num_threads); + info!("Creating {} render threads", num_threads); for i in 0..num_threads { let s = sync::Arc::clone(&scene); let pixel_req_rx = pixel_req_rx.clone(); @@ -328,6 +340,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i drop(pixel_req_tx); }); + let pixel_total = scene.width * scene.height; thread::spawn(move || { let mut last_time = time::Instant::now(); let mut last_pixel_count = PIXEL_COUNT.load(Ordering::SeqCst); @@ -339,8 +352,10 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i let time_diff = now - last_time; let pixel_diff = pixel_count - last_pixel_count; info!( - "{} pixels rendered {} p/s", + "{} / {} ({}%) pixels rendered {} p/s", pixel_count, + pixel_total, + 100 * pixel_count / pixel_total, pixel_diff as u64 / time_diff.as_secs() ); last_time = now; @@ -348,11 +363,8 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i } }); - println!("Rendering with {} subsamples", scene.subsamples); + info!("Rendering with {} subsamples", scene.subsamples); let mut img = RgbImage::new(scene.width as u32, scene.height as u32); - let total = scene.width * scene.height; - let mut cur_pixel = 0; - let mut last_progress = 1000; for resp in pixel_resp_rx { match resp { Response::Pixel { x, y, pixel } => { @@ -366,17 +378,6 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i (pixel[2] * 255.).min(255.) as u8, ]), ); - let progress = 100 * cur_pixel / total; - if progress != last_progress { - last_progress = progress; - if progress % 10 == 0 { - print!("{}%", progress); - } else { - print!("."); - } - io::stdout().flush().unwrap(); - } - cur_pixel += 1; } Response::Line { width: _, @@ -394,23 +395,10 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i (pixel[2] * 255.).min(255.) as u8, ]), ); - let progress = 100 * cur_pixel / total; - if progress != last_progress { - last_progress = progress; - if progress % 10 == 0 { - print!("{}%", progress); - } else { - print!("."); - } - io::stdout().flush().unwrap(); - } - cur_pixel += 1; } } } } - println!(); - io::stdout().flush().unwrap(); let path = output_dir.join("final.png"); // Write the contents of this image to the Writer in PNG format. trace!(target: "renderer", "Saving {}", path.display());