Reputation: 21
I'm trying to make a web server with a prometheus endpoint to put out metrics on my other pages. I'm running into an issue with collecting those metrics. It stems from warp seemingly executing each route on every request, with every route that that request doesn't match returning a 404.
Here's a toy example:
https://github.com/myaple/warp-test/tree/master/src
main.rs
extern crate warp;
extern crate tokio;
extern crate fern;
use warp::Filter;
#[tokio::main]
async fn main() {
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.level(log::LevelFilter::Debug)
.chain(std::io::stdout())
.apply();
let hlog = warp::log("hlog");
let glog = warp::log("glog");
// GET /hello/warp => 200 OK with body "Hello, warp!"
let hello = warp::path!("hello" / String)
.map(|name| format!("Hello, {}!", name))
.with(hlog);
let goodbye = warp::path!("goodbye")
.map(|| format!("goodbye"))
.with(glog);
let routes = hello.or(goodbye);
warp::serve(routes)
.run(([127, 0, 0, 1], 8080))
.await;
}
With this example, if I hit localhost:8080/goodbye, I also see a return of 404 in the logs from hlog, which is attached to /hello:
[2022-06-27][18:57:59][warp::server][INFO] Server::run; addr=127.0.0.1:8080
[2022-06-27][18:57:59][warp::server][INFO] listening on http://127.0.0.1:8080
[2022-06-27][18:58:04][hyper::proto::h1::io][DEBUG] parsed 12 headers
[2022-06-27][18:58:04][hyper::proto::h1::conn][DEBUG] incoming body is empty
[2022-06-27][18:58:04][hlog][INFO] 127.0.0.1:62698 "GET /goodbye HTTP/1.1" 404 "-" "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0" 68µs
[2022-06-27][18:58:04][glog][INFO] 127.0.0.1:62698 "GET /goodbye HTTP/1.1" 200 "-" "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0" 25.3µs
[2022-06-27][18:58:04][hyper::proto::h1::io][DEBUG] flushed 123 bytes
[2022-06-27][18:58:04][hyper::proto::h1::io][DEBUG] parsed 11 headers
[2022-06-27][18:58:04][hyper::proto::h1::conn][DEBUG] incoming body is empty
[2022-06-27][18:58:04][hyper::server::server::new_svc][DEBUG] connection error: connection closed before message completed
Similar to this example, if I attach a function in a .with()
that increments a counter for every 404 I generate, every good request matched by a route is also sending back multiple 404s from every other route that it didn't match with.
Is there a good way to weed out these requests so they either do not execute, or is there some functionality I'm missing that allows me to not log and not observe metrics on unmatched routes?
Upvotes: 1
Views: 194
Reputation: 21
As cdhowie pointed out in the comment, you can just add the log filter at the top level pipeline:
extern crate warp;
extern crate tokio;
extern crate fern;
use warp::Filter;
#[tokio::main]
async fn main() {
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.level(log::LevelFilter::Debug)
.chain(std::io::stdout())
.apply();
let access_log = warp::log("access_log");
// GET /hello/warp => 200 OK with body "Hello, warp!"
let hello = warp::path!("hello" / String)
.map(|name| format!("Hello, {}!", name));
let goodbye = warp::path!("goodbye")
.map(|| format!("goodbye"));
let routes = hello.or(goodbye).with(access_log);
warp::serve(routes)
.run(([127, 0, 0, 1], 8080))
.await;
}
Upvotes: 1