From f837312f3a162daa865600c5248589935d2aac57 Mon Sep 17 00:00:00 2001 From: Vika Date: Wed, 2 Mar 2022 23:41:11 +0300 Subject: metrics: new metrics collection using warp-prometheus --- Cargo.lock | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 8 +++++- src/metrics.rs | 76 ++++---------------------------------------------- 3 files changed, 95 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a6b68f..1a92ad8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,7 +1129,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha-1", + "sha-1 0.10.0", ] [[package]] @@ -1443,6 +1443,7 @@ dependencies = [ "hyper", "hyper-rustls", "lazy_static", + "listenfd", "log 0.4.14", "markdown", "markup", @@ -1461,8 +1462,10 @@ dependencies = [ "tempdir", "test-logger", "tokio", + "tokio-stream", "url", "warp", + "warp-prometheus", ] [[package]] @@ -1558,6 +1561,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "listenfd" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02b14f35d9f5f082fd0b1b34aa0ef32e3354c859c721d7f3325b3f79a42ba54" +dependencies = [ + "libc", + "uuid", + "winapi 0.3.9", +] + [[package]] name = "lock_api" version = "0.4.5" @@ -2040,9 +2054,9 @@ dependencies = [ [[package]] name = "procfs" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd" +checksum = "95e344cafeaeefe487300c361654bcfc85db3ac53619eeccced29f5ea18c4c70" dependencies = [ "bitflags", "byteorder", @@ -2054,9 +2068,9 @@ dependencies = [ [[package]] name = "prometheus" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5986aa8d62380092d2f50f8b1cdba9cb9b6731ffd4b25b51fd126b6c3e05b99c" +checksum = "b7f64969ffd5dd8f39bd57a68ac53c163a095ed9d0fb707146da1b27025a3504" dependencies = [ "cfg-if", "fnv", @@ -2530,6 +2544,19 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha-1" version = "0.10.0" @@ -2971,6 +2998,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" +dependencies = [ + "futures-util", + "log 0.4.14", + "pin-project", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.6.9" @@ -3040,6 +3080,25 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log 0.4.14", + "rand 0.8.4", + "sha-1 0.9.8", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "twoway" version = "0.1.8" @@ -3132,6 +3191,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + [[package]] name = "value-bag" version = "1.0.0-alpha.8" @@ -3195,11 +3260,23 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-stream", + "tokio-tungstenite", "tokio-util", "tower-service", "tracing", ] +[[package]] +name = "warp-prometheus" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63a77e844a8110e3551913c18f4f215e2c58dd9193668449fa34b67c205524a1" +dependencies = [ + "log 0.4.14", + "prometheus", + "warp", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index d4cfb72..e858f91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ name = "kittybox" version = "0.1.0" authors = ["Vika "] edition = "2021" +default-run = "kittybox" [features] default = [] @@ -43,6 +44,7 @@ fd-lock = "^3.0.0" # Advisory reader-writer locks for files futures = "^0.3.14" # An implementation of futures and streams futures-util = "^0.3.14" # Common utilities and extension traits for the futures-rs library lazy_static = "^1.4.0" # A macro for declaring lazily evaluated statics in Rust +listenfd = "^0.5.0" # A simple library to work with listenfds passed from the outside (systemd/catflap socket activation) log = "^0.4.14" # A lightweight logging facade for Rust markdown = "^0.3.0" # Native Rust library for parsing Markdown and (outputting HTML) markup = "^0.12.0" # HTML templating engine... ok also very funny about markdown and markup... i just realized the pun... @@ -53,9 +55,13 @@ serde_json = "^1.0.64" # A JSON serialization file format serde_urlencoded = "^0.7.0" # `x-www-form-urlencoded` meets Serde relative-path = "^1.5.0" # Portable relative paths for Rust sha2 = "^0.9.8" # SHA-2 series of algorithms for Rust +warp-prometheus = "^0.5.0" # An afterthought of prometheus metrics for Warp [dependencies.tokio] version = "^1.16.1" features = ["full"] # TODO determine if my app doesn't need some features +[dependencies.tokio-stream] +version = "^0.1.8" +features = ["time", "net"] [dependencies.anyhow] version = "^1.0.42" optional = true @@ -67,7 +73,7 @@ version = "^0.21.3" optional = true features = ["aio", "tokio-comp"] [dependencies.prometheus] # Prometheus instrumentation library for Rust applications -version = "^0.12.0" +version = "^0.13.0" features = ["process"] [dependencies.serde] # A generic serialization/deserialization framework version = "^1.0.125" diff --git a/src/metrics.rs b/src/metrics.rs index 7bfa2d2..48f5d9b 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,83 +1,19 @@ #![allow(unused_imports, dead_code)] use async_trait::async_trait; use lazy_static::lazy_static; -use prometheus::{ - self, register_histogram_vec, register_int_counter_vec, Encoder, HistogramVec, IntCounterVec, - TextEncoder, -}; use std::time::{Duration, Instant}; -//use tide::{Next, Request, Response, Result}; +use prometheus::Encoder; -// Copied from https://docs.rs/prometheus/0.12.0/src/prometheus/histogram.rs.html#885-889 -#[inline] -fn duration_to_seconds(d: Duration) -> f64 { - let nanos = f64::from(d.subsec_nanos()) / 1e9; - d.as_secs() as f64 + nanos -} +// TODO: Vendor in the Metrics struct from warp_prometheus and rework the path matching algorithm -lazy_static! { - static ref HTTP_CONNS_COUNTER: IntCounterVec = register_int_counter_vec!( - "http_requests_total", - "Number of processed HTTP requests", - &["code", "method", "url"] - ) - .unwrap(); - static ref HTTP_REQUEST_DURATION_HISTOGRAM: HistogramVec = register_histogram_vec!( - "http_request_duration_seconds", - "Duration of HTTP requests", - &["code", "method", "url"] - ) - .unwrap(); +pub fn metrics(path_includes: Vec) -> warp::log::Log { + let metrics = warp_prometheus::Metrics::new(prometheus::default_registry(), &path_includes); + warp::log::custom(move |info| metrics.http_metrics(info)) } -/*pub struct InstrumentationMiddleware {} - -#[async_trait] -impl tide::Middleware for InstrumentationMiddleware -where - S: Send + Sync + Clone + 'static, -{ - async fn handle(&self, req: Request, next: Next<'_, S>) -> Result { - let url = req.url().to_string(); - let method = req.method().to_string(); - // Execute the request - let instant = Instant::now(); - let res = next.run(req).await; - let elapsed = duration_to_seconds(instant.elapsed()); - // Get the code from the response - let code = res.status().to_string(); - - HTTP_CONNS_COUNTER - .with_label_values(&[&code, &method, &url]) - .inc(); - HTTP_REQUEST_DURATION_HISTOGRAM - .with_label_values(&[&code, &method, &url]) - .observe(elapsed); - - Ok(res) - } -}*/ - -/*pub async fn gather(_: Request) -> Result -where - S: Send + Sync + Clone, -{ - let mut buffer: Vec = vec![]; - let encoder = TextEncoder::new(); - let metric_families = prometheus::gather(); - encoder.encode(&metric_families, &mut buffer).unwrap(); - - Ok(Response::builder(200).body(buffer).build()) -}*/ - -// TODO metrics middleware -// warp doesn't allow running a filter manually -// so you need to escape into the world of hyper -// to collect metrics on requests - pub fn gather() -> Vec { let mut buffer: Vec = vec![]; - let encoder = TextEncoder::new(); + let encoder = prometheus::TextEncoder::new(); let metric_families = prometheus::gather(); encoder.encode(&metric_families, &mut buffer).unwrap(); -- cgit 1.4.1