From d2aa675b39361eccb1f5e74b08bc6428f564daa3 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Sat, 16 Oct 2021 09:15:48 +0400 Subject: [PATCH] Add prometheus --- Cargo.lock | 53 +++++++++ cargo/crates.bzl | 50 ++++++++ cargo/remote/BUILD.adler-1.0.2.bazel | 55 +++++++++ cargo/remote/BUILD.crc32fast-1.2.1.bazel | 90 +++++++++++++++ cargo/remote/BUILD.flate2-1.0.22.bazel | 127 +++++++++++++++++++++ cargo/remote/BUILD.miniz_oxide-0.4.4.bazel | 85 ++++++++++++++ cargo/remote/BUILD.procfs-0.9.1.bazel | 81 +++++++++++++ cargo/remote/BUILD.prometheus-0.12.0.bazel | 8 ++ common/rust/Cargo.toml | 2 +- config/default.json | 18 ++- rest/src/proxy/mod.rs | 50 ++++++-- webhook/src/handler/signature.rs | 25 +++- 12 files changed, 630 insertions(+), 14 deletions(-) create mode 100644 cargo/remote/BUILD.adler-1.0.2.bazel create mode 100644 cargo/remote/BUILD.crc32fast-1.2.1.bazel create mode 100644 cargo/remote/BUILD.flate2-1.0.22.bazel create mode 100644 cargo/remote/BUILD.miniz_oxide-0.4.4.bazel create mode 100644 cargo/remote/BUILD.procfs-0.9.1.bazel diff --git a/Cargo.lock b/Cargo.lock index dfdd79d..c25dbfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.18" @@ -266,6 +272,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -400,6 +415,18 @@ dependencies = [ "instant", ] +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -845,6 +872,16 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "mio" version = "0.7.13" @@ -1229,6 +1266,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "procfs" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd" +dependencies = [ + "bitflags", + "byteorder", + "flate2", + "hex", + "lazy_static", + "libc", +] + [[package]] name = "prometheus" version = "0.12.0" @@ -1238,8 +1289,10 @@ dependencies = [ "cfg-if", "fnv", "lazy_static", + "libc", "memchr", "parking_lot", + "procfs", "protobuf", "thiserror", ] diff --git a/cargo/crates.bzl b/cargo/crates.bzl index 00b9b60..b0def28 100644 --- a/cargo/crates.bzl +++ b/cargo/crates.bzl @@ -251,6 +251,16 @@ def _flatten_dependency_maps(all_dependency_maps): def raze_fetch_remote_crates(): """This function defines a collection of repos and should be called in a WORKSPACE file""" + maybe( + http_archive, + name = "raze__adler__1_0_2", + url = "https://crates.io/api/v1/crates/adler/1.0.2/download", + type = "tar.gz", + sha256 = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe", + strip_prefix = "adler-1.0.2", + build_file = Label("//cargo/remote:BUILD.adler-1.0.2.bazel"), + ) + maybe( http_archive, name = "raze__aho_corasick__0_7_18", @@ -531,6 +541,16 @@ def raze_fetch_remote_crates(): build_file = Label("//cargo/remote:BUILD.crc16-0.4.0.bazel"), ) + maybe( + http_archive, + name = "raze__crc32fast__1_2_1", + url = "https://crates.io/api/v1/crates/crc32fast/1.2.1/download", + type = "tar.gz", + sha256 = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a", + strip_prefix = "crc32fast-1.2.1", + build_file = Label("//cargo/remote:BUILD.crc32fast-1.2.1.bazel"), + ) + maybe( http_archive, name = "raze__crossbeam_channel__0_5_1", @@ -671,6 +691,16 @@ def raze_fetch_remote_crates(): build_file = Label("//cargo/remote:BUILD.fastrand-1.5.0.bazel"), ) + maybe( + http_archive, + name = "raze__flate2__1_0_22", + url = "https://crates.io/api/v1/crates/flate2/1.0.22/download", + type = "tar.gz", + sha256 = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f", + strip_prefix = "flate2-1.0.22", + build_file = Label("//cargo/remote:BUILD.flate2-1.0.22.bazel"), + ) + maybe( http_archive, name = "raze__fnv__1_0_7", @@ -1111,6 +1141,16 @@ def raze_fetch_remote_crates(): build_file = Label("//cargo/remote:BUILD.memchr-2.4.1.bazel"), ) + maybe( + http_archive, + name = "raze__miniz_oxide__0_4_4", + url = "https://crates.io/api/v1/crates/miniz_oxide/0.4.4/download", + type = "tar.gz", + sha256 = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b", + strip_prefix = "miniz_oxide-0.4.4", + build_file = Label("//cargo/remote:BUILD.miniz_oxide-0.4.4.bazel"), + ) + maybe( http_archive, name = "raze__mio__0_7_13", @@ -1481,6 +1521,16 @@ def raze_fetch_remote_crates(): build_file = Label("//cargo/remote:BUILD.proc-macro2-1.0.29.bazel"), ) + maybe( + http_archive, + name = "raze__procfs__0_9_1", + url = "https://crates.io/api/v1/crates/procfs/0.9.1/download", + type = "tar.gz", + sha256 = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd", + strip_prefix = "procfs-0.9.1", + build_file = Label("//cargo/remote:BUILD.procfs-0.9.1.bazel"), + ) + maybe( http_archive, name = "raze__prometheus__0_12_0", diff --git a/cargo/remote/BUILD.adler-1.0.2.bazel b/cargo/remote/BUILD.adler-1.0.2.bazel new file mode 100644 index 0000000..1fda177 --- /dev/null +++ b/cargo/remote/BUILD.adler-1.0.2.bazel @@ -0,0 +1,55 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "0BSD OR (MIT OR Apache-2.0)" +]) + +# Generated Targets + +# Unsupported target "bench" with type "bench" omitted + +rust_library( + name = "adler", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "1.0.2", + # buildifier: leave-alone + deps = [ + ], +) diff --git a/cargo/remote/BUILD.crc32fast-1.2.1.bazel b/cargo/remote/BUILD.crc32fast-1.2.1.bazel new file mode 100644 index 0000000..e89a779 --- /dev/null +++ b/cargo/remote/BUILD.crc32fast-1.2.1.bazel @@ -0,0 +1,90 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets +# buildifier: disable=out-of-order-load +# buildifier: disable=load-on-top +load( + "@rules_rust//cargo:cargo_build_script.bzl", + "cargo_build_script", +) + +cargo_build_script( + name = "crc32fast_build_script", + srcs = glob(["**/*.rs"]), + build_script_env = { + }, + crate_features = [ + "default", + "std", + ], + crate_root = "build.rs", + data = glob(["**"]), + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "1.2.1", + visibility = ["//visibility:private"], + deps = [ + ], +) + +# Unsupported target "bench" with type "bench" omitted + +rust_library( + name = "crc32fast", + srcs = glob(["**/*.rs"]), + crate_features = [ + "default", + "std", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "1.2.1", + # buildifier: leave-alone + deps = [ + ":crc32fast_build_script", + "@raze__cfg_if__1_0_0//:cfg_if", + ], +) diff --git a/cargo/remote/BUILD.flate2-1.0.22.bazel b/cargo/remote/BUILD.flate2-1.0.22.bazel new file mode 100644 index 0000000..27caa81 --- /dev/null +++ b/cargo/remote/BUILD.flate2-1.0.22.bazel @@ -0,0 +1,127 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets + +# Unsupported target "compress_file" with type "example" omitted + +# Unsupported target "deflatedecoder-bufread" with type "example" omitted + +# Unsupported target "deflatedecoder-read" with type "example" omitted + +# Unsupported target "deflatedecoder-write" with type "example" omitted + +# Unsupported target "deflateencoder-bufread" with type "example" omitted + +# Unsupported target "deflateencoder-read" with type "example" omitted + +# Unsupported target "deflateencoder-write" with type "example" omitted + +# Unsupported target "gzbuilder" with type "example" omitted + +# Unsupported target "gzdecoder-bufread" with type "example" omitted + +# Unsupported target "gzdecoder-read" with type "example" omitted + +# Unsupported target "gzdecoder-write" with type "example" omitted + +# Unsupported target "gzencoder-bufread" with type "example" omitted + +# Unsupported target "gzencoder-read" with type "example" omitted + +# Unsupported target "gzencoder-write" with type "example" omitted + +# Unsupported target "gzmultidecoder-bufread" with type "example" omitted + +# Unsupported target "gzmultidecoder-read" with type "example" omitted + +# Unsupported target "zlibdecoder-bufread" with type "example" omitted + +# Unsupported target "zlibdecoder-read" with type "example" omitted + +# Unsupported target "zlibdecoder-write" with type "example" omitted + +# Unsupported target "zlibencoder-bufread" with type "example" omitted + +# Unsupported target "zlibencoder-read" with type "example" omitted + +# Unsupported target "zlibencoder-write" with type "example" omitted + +rust_library( + name = "flate2", + srcs = glob(["**/*.rs"]), + aliases = { + }, + crate_features = [ + "default", + "miniz_oxide", + "rust_backend", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + compile_data = glob(["*/**"]), + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "1.0.22", + # buildifier: leave-alone + deps = [ + "@raze__cfg_if__1_0_0//:cfg_if", + "@raze__crc32fast__1_2_1//:crc32fast", + "@raze__libc__0_2_101//:libc", + "@raze__miniz_oxide__0_4_4//:miniz_oxide", + ] + selects.with_or({ + # cfg(all(target_arch = "wasm32", not(target_os = "emscripten"))) + ( + "@rules_rust//rust/platform:wasm32-unknown-unknown", + "@rules_rust//rust/platform:wasm32-wasi", + ): [ + ], + "//conditions:default": [], + }), +) + +# Unsupported target "async-reader" with type "test" omitted + +# Unsupported target "early-flush" with type "test" omitted + +# Unsupported target "empty-read" with type "test" omitted + +# Unsupported target "gunzip" with type "test" omitted + +# Unsupported target "tokio" with type "test" omitted + +# Unsupported target "zero-write" with type "test" omitted diff --git a/cargo/remote/BUILD.miniz_oxide-0.4.4.bazel b/cargo/remote/BUILD.miniz_oxide-0.4.4.bazel new file mode 100644 index 0000000..ca46c39 --- /dev/null +++ b/cargo/remote/BUILD.miniz_oxide-0.4.4.bazel @@ -0,0 +1,85 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR (Zlib OR Apache-2.0)" +]) + +# Generated Targets +# buildifier: disable=out-of-order-load +# buildifier: disable=load-on-top +load( + "@rules_rust//cargo:cargo_build_script.bzl", + "cargo_build_script", +) + +cargo_build_script( + name = "miniz_oxide_build_script", + srcs = glob(["**/*.rs"]), + build_script_env = { + }, + crate_features = [ + ], + crate_root = "build.rs", + data = glob(["**"]), + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.4.4", + visibility = ["//visibility:private"], + deps = [ + "@raze__autocfg__1_0_1//:autocfg", + ], +) + +rust_library( + name = "miniz_oxide", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.4.4", + # buildifier: leave-alone + deps = [ + ":miniz_oxide_build_script", + "@raze__adler__1_0_2//:adler", + ], +) diff --git a/cargo/remote/BUILD.procfs-0.9.1.bazel b/cargo/remote/BUILD.procfs-0.9.1.bazel new file mode 100644 index 0000000..5819e10 --- /dev/null +++ b/cargo/remote/BUILD.procfs-0.9.1.bazel @@ -0,0 +1,81 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets + +# Unsupported target "diskstat" with type "example" omitted + +# Unsupported target "dump" with type "example" omitted + +# Unsupported target "interface_stats" with type "example" omitted + +# Unsupported target "lslocks" with type "example" omitted + +# Unsupported target "lsmod" with type "example" omitted + +# Unsupported target "mountinfo" with type "example" omitted + +# Unsupported target "netstat" with type "example" omitted + +# Unsupported target "pressure" with type "example" omitted + +# Unsupported target "process_hierarchy" with type "example" omitted + +# Unsupported target "ps" with type "example" omitted + +# Unsupported target "self_memory" with type "example" omitted + +rust_library( + name = "procfs", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.9.1", + # buildifier: leave-alone + deps = [ + "@raze__bitflags__1_3_2//:bitflags", + "@raze__byteorder__1_4_3//:byteorder", + "@raze__flate2__1_0_22//:flate2", + "@raze__hex__0_4_3//:hex", + "@raze__lazy_static__1_4_0//:lazy_static", + "@raze__libc__0_2_101//:libc", + ], +) diff --git a/cargo/remote/BUILD.prometheus-0.12.0.bazel b/cargo/remote/BUILD.prometheus-0.12.0.bazel index d448c8a..a9b0de3 100644 --- a/cargo/remote/BUILD.prometheus-0.12.0.bazel +++ b/cargo/remote/BUILD.prometheus-0.12.0.bazel @@ -43,6 +43,9 @@ cargo_build_script( }, crate_features = [ "default", + "libc", + "process", + "procfs", "protobuf", ], crate_root = "build.rs", @@ -106,6 +109,9 @@ rust_library( }, crate_features = [ "default", + "libc", + "process", + "procfs", "protobuf", ], crate_root = "src/lib.rs", @@ -126,6 +132,7 @@ rust_library( "@raze__cfg_if__1_0_0//:cfg_if", "@raze__fnv__1_0_7//:fnv", "@raze__lazy_static__1_4_0//:lazy_static", + "@raze__libc__0_2_101//:libc", "@raze__memchr__2_4_1//:memchr", "@raze__parking_lot__0_11_2//:parking_lot", "@raze__protobuf__2_25_1//:protobuf", @@ -140,6 +147,7 @@ rust_library( "@rules_rust//rust/platform:s390x-unknown-linux-gnu", "@rules_rust//rust/platform:x86_64-unknown-linux-gnu", ): [ + "@raze__procfs__0_9_1//:procfs", ], "//conditions:default": [], }), diff --git a/common/rust/Cargo.toml b/common/rust/Cargo.toml index e546cba..d54eea9 100644 --- a/common/rust/Cargo.toml +++ b/common/rust/Cargo.toml @@ -10,7 +10,7 @@ serde = { version = "1.0.8", features = ["derive"] } config = "0.11" hyper = { version = "0.14", features = ["full"] } tokio = { version = "1", features = ["full"] } -prometheus = "0.12.0" +prometheus = { version = "0.12.0", features = ["process"] } nats = "0.15.2" testcontainers = "0.12.0" diff --git a/config/default.json b/config/default.json index 70d00d3..51a8729 100644 --- a/config/default.json +++ b/config/default.json @@ -1,10 +1,15 @@ { "monitoring": { - "enabled": false + "enabled": true, + "address": "0.0.0.0", + "port": 5001 }, "nats": { "host": "localhost" }, + "redis": { + "url": "redis://localhost" + }, "rest": { "server": { "port": 8000, @@ -14,7 +19,14 @@ "token": "" } }, - "redis": { - "url": "redis://localhost" + "webhook": { + "server": { + "port": 8080, + "address": "0.0.0.0" + }, + "discord": { + "public_key": "", + "client_id": 123 + } } } \ No newline at end of file diff --git a/rest/src/proxy/mod.rs b/rest/src/proxy/mod.rs index dc0be03..f07d995 100644 --- a/rest/src/proxy/mod.rs +++ b/rest/src/proxy/mod.rs @@ -1,23 +1,45 @@ use crate::{config::Config, ratelimit::Ratelimiter}; -use common::log::debug; -use futures_util::future::TryFutureExt; +use common::{log::debug, prometheus::{Counter, HistogramVec, labels, opts, register_counter, register_histogram_vec}}; use hyper::{ client::HttpConnector, header::HeaderValue, http::uri::Parts, service::Service, Body, Client, HeaderMap, Request, Response, Uri, }; use hyper_tls::HttpsConnector; +use tokio::sync::Mutex; use std::{future::Future, pin::Pin, sync::Arc, task::Poll}; +lazy_static::lazy_static! { + static ref HTTP_COUNTER: Counter = register_counter!(opts!( + "nova_rest_http_requests_total", + "Number of HTTP requests made.", + labels! {"handler" => "all",} + )) + .unwrap(); + + static ref HTTP_REQ_HISTOGRAM: HistogramVec = register_histogram_vec!( + "nova_rest_http_request_duration_seconds", + "The HTTP request latencies in seconds.", + &["handler"] + ) + .unwrap(); + + static ref HTTP_COUNTER_STATUS: Counter = register_counter!(opts!( + "nova_rest_http_requests_status", + "Number of HTTP requests made by status", + labels! {"" => ""} + )) + .unwrap(); +} + + #[derive(Clone)] pub struct ServiceProxy { client: Client>, ratelimiter: Arc, config: Arc, + fail: Arc>, } -impl ServiceProxy { - async fn proxy_call() {} -} impl Service> for ServiceProxy { type Response = Response; @@ -36,6 +58,9 @@ impl Service> for ServiceProxy { } fn call(&mut self, mut req: Request) -> Self::Future { + HTTP_COUNTER.inc(); + + let timer = HTTP_REQ_HISTOGRAM.with_label_values(&["all"]).start_timer(); let host = "discord.com"; let mut new_parts = Parts::default(); @@ -58,9 +83,10 @@ impl Service> for ServiceProxy { *req.headers_mut() = headers; let client = self.client.clone(); let ratelimiter = self.ratelimiter.clone(); + let fail = self.fail.clone(); return Box::pin(async move { - match ratelimiter.before_request(&req).await { + let resp = match ratelimiter.before_request(&req).await { Ok(allowed) => match allowed { crate::ratelimit::RatelimiterResponse::Ratelimited => { debug!("ratelimited"); @@ -69,8 +95,12 @@ impl Service> for ServiceProxy { _ => { debug!("forwarding request"); match client.request(req).await { - Ok(response) => { + Ok(mut response) => { ratelimiter.after_request(&path, &response).await; + if response.status() != 200 { + *fail.lock().await += 1 + } + response.headers_mut().insert("x-fails", HeaderValue::from_str(&format!("{}", fail.lock().await)).unwrap()); Ok(response) } Err(e) => Err(e), @@ -80,7 +110,9 @@ impl Service> for ServiceProxy { Err(e) => Ok(Response::builder() .body(format!("server error: {}", e).into()) .unwrap()), - } + }; + timer.observe_duration(); + resp }); } } @@ -89,10 +121,12 @@ impl ServiceProxy { pub fn new(config: Arc, ratelimiter: Arc) -> Self { let https = HttpsConnector::new(); let client = Client::builder().build::<_, hyper::Body>(https); + let fail = Arc::new(Mutex::new(0)); ServiceProxy { client, config, ratelimiter, + fail } } } diff --git a/webhook/src/handler/signature.rs b/webhook/src/handler/signature.rs index b98af51..c12f9e8 100644 --- a/webhook/src/handler/signature.rs +++ b/webhook/src/handler/signature.rs @@ -1,11 +1,30 @@ +use common::prometheus::{Counter, HistogramVec, labels, opts, register_counter, register_histogram_vec}; use libsodium_sys::crypto_sign_ed25519_verify_detached; +lazy_static::lazy_static! { + static ref SIGNATURE_TIME_HISTOGRAM: HistogramVec = register_histogram_vec!( + "nova_webhook_signature_time", + "The time taken by the signature verification", + &["signature"] + ).unwrap(); + + static ref SIGNATURE_BODY_COUNTER: Counter = register_counter!(opts!( + "nova_webhook_", + "", + labels! {"handler" => "webhook_main"} + )).unwrap(); +} + /// Checks the signature of a given data using the hex signature and the public key. pub fn validate_signature(hex_public_key: &str, data: &Vec, hex_signature: &str) -> bool { + SIGNATURE_BODY_COUNTER.inc(); + let timer = SIGNATURE_TIME_HISTOGRAM.with_label_values(&["webhook_main"]).start_timer(); + // First, we need to check if the signature & private key is valid base64. let signature_result = hex::decode(hex_signature); let public_key_result = hex::decode(hex_public_key); + let mut result = false; if signature_result.is_ok() && public_key_result.is_ok() { // Since we now have the signatures in u8 vectors. We will initialize all the // parameters for the ffi call to sodium. @@ -19,7 +38,7 @@ pub fn validate_signature(hex_public_key: &str, data: &Vec, hex_signature: & // we assume all the parameters are correct for the call unsafe { // If the signature is valid, sodium will return 0 - return crypto_sign_ed25519_verify_detached( + result = crypto_sign_ed25519_verify_detached( signature_pointer.as_ptr(), data_pointer, data_len, @@ -27,5 +46,7 @@ pub fn validate_signature(hex_public_key: &str, data: &Vec, hex_signature: & ) == 0; } } - false + + timer.observe_duration(); + result } -- 2.39.5