about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2022-03-02 23:41:11 +0300
committerVika <vika@fireburn.ru>2022-03-02 23:41:11 +0300
commitf837312f3a162daa865600c5248589935d2aac57 (patch)
tree7cb460cd05738dbdb4aa61e1194348e156094d16
parent56e1022da6f260eb5a91e9de090b58d9dbd58cf2 (diff)
metrics: new metrics collection using warp-prometheus
-rw-r--r--Cargo.lock87
-rw-r--r--Cargo.toml8
-rw-r--r--src/metrics.rs76
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]]
@@ -1559,6 +1562,17 @@ dependencies = [
 ]
 
 [[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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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",
@@ -2532,6 +2546,19 @@ dependencies = [
 
 [[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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
@@ -2972,6 +2999,19 @@ dependencies = [
 ]
 
 [[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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3041,6 +3081,25 @@ 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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3133,6 +3192,12 @@ 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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3195,12 +3260,24 @@ 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"
 source = "registry+https://github.com/rust-lang/crates.io-index"
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 <vika@fireburn.ru>"]
 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<String>) -> warp::log::Log<impl Fn(warp::log::Info) + Clone> {
+    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<S> tide::Middleware<S> for InstrumentationMiddleware
-where
-    S: Send + Sync + Clone + 'static,
-{
-    async fn handle(&self, req: Request<S>, 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<S>(_: Request<S>) -> Result
-where
-    S: Send + Sync + Clone,
-{
-    let mut buffer: Vec<u8> = 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<u8> {
     let mut buffer: Vec<u8> = vec![];
-    let encoder = TextEncoder::new();
+    let encoder = prometheus::TextEncoder::new();
     let metric_families = prometheus::gather();
     encoder.encode(&metric_families, &mut buffer).unwrap();