I have a basic web server running warp, and I want to add a basic logging feature that can write to a logfile. However, this is proving much more difficult than I would expect, since the map function that comes with the Filter trait doesn't let you pass in a FnMut closure type.
Here's a piece of code that I would like to work, but doesn't
let mut log_file = OpenOptions::new()
.write(true)
.create(true)
.open(log_file_path)
.expect("couldn't open or create log file");
let pending_handler = warp::path("pending").and(warp::body::json()).map(
|mut req_body: HashMap<String, String>| {
// Do something here
let log = "Some log".to_owned();
// THIS DOES NOT WORK
log_file.write_all(log.as_bytes()).unwrap();
"OK".to_owned()
});
// Serve warp routes here
What am I missing? Are there any workarounds? Any help would be appreciated
You should never use std::fs in async code. Use tokio::fs instead. You should wrap the file in a tokio::sync::Mutex so that access to it is synchronized between tasks. Also you'll need and_then not map to allow you to use async operations.
Consider using a library like log or tracing instead of manually implementing logging. They will both allow you to log to a file I believe, and are well-supported in the ecosystem.
To add to @Kestrer, I often use simplelog if I just need to do some logging to a file. Very easy. And then you can use something like log::info!() in your program whenever you need to write to the log without needing to pass around a file handle.