diff options
Diffstat (limited to 'src/filters/accesslog.rs')
-rw-r--r-- | src/filters/accesslog.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/filters/accesslog.rs b/src/filters/accesslog.rs new file mode 100644 index 0000000..ff5a8d5 --- /dev/null +++ b/src/filters/accesslog.rs @@ -0,0 +1,48 @@ +use crate::{config::AccessLogConfig, error::ServiceError, FilterRequest, State}; +use futures::executor::block_on; +use log::error; +use std::{net::SocketAddr, ops::ControlFlow}; +use tokio::{ + fs::OpenOptions, + io::{AsyncWriteExt, BufWriter}, +}; + +pub async fn access_log( + state: &State, + host: &str, + addr: SocketAddr, + config: &AccessLogConfig, + req: &FilterRequest, +) -> Result<ControlFlow<()>, ServiceError> { + let mut g = state.access_logs.write().await; + + let log = g.entry(host.to_owned()).or_insert_with(|| { + BufWriter::new( + // TODO aaahh dont block the runtime and dont panic in any case.... + block_on( + OpenOptions::new() + .append(true) + .create(true) + .open(&config.file), + ) + .unwrap(), + ) + }); + + let method = req.method().as_str(); + let mut res = log + .write_all(format!("{addr}\t{method}\t{:?}\n", req.uri()).as_bytes()) + .await; + + if config.flush && res.is_ok() { + res = log.flush().await; + } + + if config.reject_on_fail { + res? + } else if let Err(e) = res { + error!("failed to write log: {e:?}") + } + + Ok(ControlFlow::Continue(())) +} |