Compare commits

..

3 commits

Author SHA1 Message Date
Armaël Guéneau
2999e366d8 Have more tags in the in_flight_requests meter (eg "service")
The host tag is not currently included, but could be added later with
some refactorings if we need it.
2024-05-01 11:43:11 +02:00
Armaël Guéneau
1f621cd2a5 add small comment 2024-04-26 13:11:25 +02:00
Armaël Guéneau
68980642e1 Add a metrics counter measuring in-flight requests 2024-04-25 22:22:45 +02:00
6 changed files with 1376 additions and 2375 deletions

1194
Cargo.lock generated

File diff suppressed because it is too large Load diff

2403
Cargo.nix

File diff suppressed because it is too large Load diff

84
flake.lock generated
View file

@ -10,17 +10,17 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1713199118,
"narHash": "sha256-MlLdAvk+zXCFUy280sY6LqtykqWXIkKVXo72J7a6HlU=",
"owner": "cargo2nix",
"lastModified": 1666087781,
"narHash": "sha256-trKVdjMZ8mNkGfLcY5LsJJGtdV3xJDZnMVrkFjErlcs=",
"owner": "Alexis211",
"repo": "cargo2nix",
"rev": "1efb03f2f794ad5eed17e807e858c4da001dbc3e",
"rev": "a7a61179b66054904ef6a195d8da736eaaa06c36",
"type": "github"
},
"original": {
"owner": "cargo2nix",
"owner": "Alexis211",
"repo": "cargo2nix",
"rev": "1efb03f2f794ad5eed17e807e858c4da001dbc3e",
"rev": "a7a61179b66054904ef6a195d8da736eaaa06c36",
"type": "github"
}
},
@ -55,47 +55,93 @@
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1731094700,
"narHash": "sha256-lSiVjHP7sgnCt2hZabnq+tCLmBerDKmAdd2CS6BrBjw=",
"lastModified": 1696234590,
"narHash": "sha256-mgOzQYTvaTT4bFopVOadlndy2RPwLy60rDjIWOGujwo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "551ba0fa7653afb9d590db225c3bcbccf68931c0",
"rev": "f902cb49892d300ff15cb237e48aa1cad79d68c3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1665657542,
"narHash": "sha256-mojxNyzbvmp8NtVtxqiHGhRfjCALLfk9i/Uup68Y5q8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a3073c49bc0163fea6a121c276f526837672b555",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "551ba0fa7653afb9d590db225c3bcbccf68931c0",
"rev": "a3073c49bc0163fea6a121c276f526837672b555",
"type": "github"
}
},
"root": {
"inputs": {
"cargo2nix": "cargo2nix",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs_2"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"cargo2nix",
"nixpkgs"
]
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1731032894,
"narHash": "sha256-dQSyYPmrQiPr+PGEd+K8038rubFGz7G/dNXVeaGWE0w=",
"lastModified": 1682389182,
"narHash": "sha256-8t2nmFnH+8V48+IJsf8AK51ebXNlVbOSVYOpiqJKvJE=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d52f2a4c103a0acf09ded857b9e2519ae2360e59",
"rev": "74f1a64dd28faeeb85ef081f32cad2989850322c",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d52f2a4c103a0acf09ded857b9e2519ae2360e59",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}

View file

@ -1,43 +1,31 @@
{
description = "Tricot, a reverse proxy with consul integration";
description = "A very basic flake";
# Nixpkgs 24.05 as of 2024-11-08, has rustc v1.77.2
inputs.nixpkgs.url =
"github:NixOS/nixpkgs/551ba0fa7653afb9d590db225c3bcbccf68931c0";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/a3073c49bc0163fea6a121c276f526837672b555";
inputs.cargo2nix = {
# cargo2nix as of 2024-04-25
# NB: upgrading to a more recent commit of cargo2nix will not work (as of 2024-11-08),
# because the patch making openssl-sys cross-compilation work has been reverted.
# (patch: https://github.com/cargo2nix/cargo2nix/pull/237,
# revert: https://github.com/cargo2nix/cargo2nix/commit/cfd086deb565314f3a11b5bb25807a3ce17315d4)
url = "github:cargo2nix/cargo2nix/1efb03f2f794ad5eed17e807e858c4da001dbc3e";
# As of 2022-10-18: two small patches over unstable branch, one for clippy and one to fix feature detection
url = "github:Alexis211/cargo2nix/a7a61179b66054904ef6a195d8da736eaaa06c36";
# Rust overlay as of 2024-11-08
# Rust overlay as of 2023-04-25
inputs.rust-overlay.url =
"github:oxalica/rust-overlay/d52f2a4c103a0acf09ded857b9e2519ae2360e59";
"github:oxalica/rust-overlay/74f1a64dd28faeeb85ef081f32cad2989850322c";
inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, cargo2nix }:
let
targetHost = "x86_64-unknown-linux-musl";
pkgs = import nixpkgs {
system = "x86_64-linux";
crossSystem = {
config = targetHost;
isStatic = true;
};
overlays = [ cargo2nix.overlays.default ];
};
packageFun = import ./Cargo.nix;
rustVersion = "1.77.2";
rustVersion = "1.68.0";
compile = args: compileMode:
let
packageSet = pkgs.rustBuilder.makePackageSet ({
inherit packageFun rustVersion;
target = targetHost;
} // args);
in
packageSet.workspace.tricot {
@ -49,13 +37,5 @@
debug.x86_64-linux.tricot = compile { release = false; } "build";
packages.x86_64-linux.tricot = compile { release = true; } "build";
packages.x86_64-linux.default = self.packages.x86_64-linux.tricot;
docker = pkgs.dockerTools.buildImage {
name = "tricot";
config = {
contents = [ pkgs.cacert ];
Cmd = [ "${self.packages.x86_64-linux.default}/bin/tricot" ];
};
};
};
}

View file

@ -41,9 +41,21 @@ pub struct HttpsConfig {
struct HttpsMetrics {
requests_received: metrics::Counter<u64>,
requests_served: metrics::Counter<u64>,
requests_in_flight: metrics::UpDownCounter<i64>,
request_proxy_duration: metrics::Histogram<f64>,
}
struct InFlightGuard<'a, 'b> {
metrics: &'a HttpsMetrics,
tags: &'b [KeyValue],
}
impl<'a, 'b> Drop for InFlightGuard<'a, 'b> {
fn drop(&mut self) {
self.metrics.requests_in_flight.add(-1, self.tags)
}
}
pub async fn serve_https(
config: HttpsConfig,
cert_store: Arc<CertStore>,
@ -62,6 +74,10 @@ pub async fn serve_https(
.u64_counter("https_requests_served")
.with_description("Total number of requests served over HTTPS")
.init(),
requests_in_flight: meter
.i64_up_down_counter("https_requests_in_flight")
.with_description("Current number of requests handled over HTTPS")
.init(),
request_proxy_duration: meter
.f64_histogram("https_request_proxy_duration")
.with_description("Duration between time when request was received, and time when backend returned status code and headers")
@ -178,9 +194,7 @@ async fn handle_request(
.unwrap_or_default(),
);
metrics
.requests_received
.add(1, &[host_tag, method_tag.clone()]);
metrics.requests_received.add(1, &[host_tag, method_tag.clone()]);
let mut tags = vec![method_tag];
let resp = select_target_and_proxy(
@ -272,6 +286,17 @@ async fn select_target_and_proxy(
);
proxy_to.calls_in_progress.fetch_add(1, Ordering::SeqCst);
let tags_in_flight = &tags.clone();
metrics.requests_in_flight.add(1, &tags_in_flight);
// The guard ensures that we decrement requests_in_flight in all cases where
// the current tasks ends, including the case where it gets canceled and
// doesn't run to completion (which may happen e.g. if it timeouts).
// (Crucially we create the guard before the first .await in this function.)
let _guard = InFlightGuard {
metrics: &metrics,
tags: &tags_in_flight,
};
// Forward to backend
debug!("{}{} -> {}", host, path, proxy_to);
trace!("Request: {:?}", req);
@ -371,8 +396,8 @@ async fn do_proxy(
reverse_proxy::call(remote_addr.ip(), &to_addr, req).await?
};
if response.status().is_success() || response.status().is_redirection() {
// (TODO: maybe we want to add these headers even if it's not a success or redirection?)
if response.status().is_success() {
// (TODO: maybe we want to add these headers even if it's not a success?)
for (header, value) in proxy_to.add_headers.iter() {
response.headers_mut().insert(
HeaderName::from_bytes(header.as_bytes())?,

View file

@ -132,7 +132,6 @@ async fn main() {
let opt = Opt::from_args();
info!("Starting Tricot");
println!("Starting Tricot");
let (exit_signal, provoke_exit) = watch_ctrl_c();
let exit_on_err = move |err: anyhow::Error| {