-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
99 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use super::summary; | ||
use crate::{data_dir_file, Result}; | ||
use actix_web::{ | ||
body::MessageBody, | ||
dev::{ServiceRequest, ServiceResponse}, | ||
middleware::Next, | ||
Error, HttpMessage, HttpRequest, | ||
}; | ||
use rusqlite::Connection; | ||
use std::time::Instant; | ||
use time::OffsetDateTime; | ||
|
||
thread_local! { | ||
static CONN: Connection = open_conn().unwrap_or_else(|e| { | ||
eprintln!("Failed to open logger connection: {e}"); | ||
std::process::exit(1) | ||
}); | ||
} | ||
|
||
fn open_conn() -> Result<Connection> { | ||
let conn = Connection::open(data_dir_file("log.db")?)?; | ||
conn.pragma_update(None, "journal_mode", "WAL")?; | ||
conn.pragma_update(None, "synchronous", "NORMAL")?; | ||
summary::init(&conn)?; | ||
Ok(conn) | ||
} | ||
|
||
pub struct RequestExtension { | ||
pub endpoint: String, | ||
pub entities: i64, | ||
} | ||
|
||
impl RequestExtension { | ||
pub fn new(endpoint: &str, entities: i64) -> Self { | ||
RequestExtension { | ||
endpoint: endpoint.into(), | ||
entities, | ||
} | ||
} | ||
} | ||
|
||
pub async fn handle_request( | ||
req: ServiceRequest, | ||
next: Next<impl MessageBody>, | ||
) -> Result<ServiceResponse<impl MessageBody>, Error> { | ||
let started_at = Instant::now(); | ||
let res = next.call(req).await; | ||
let Ok(res) = res else { return res }; | ||
let extensions = res.request().extensions(); | ||
let Some(extension) = extensions.get::<RequestExtension>() else { | ||
drop(extensions); | ||
return Ok(res); | ||
}; | ||
let endpoint = extension.endpoint.clone(); | ||
let entities = extension.entities; | ||
drop(extensions); | ||
let time_ns = Instant::now().duration_since(started_at).as_nanos(); | ||
log_summary(res.request(), &endpoint, entities, time_ns as i64)?; | ||
Ok(res) | ||
} | ||
|
||
fn log_summary(req: &HttpRequest, endpoint_id: &str, entities: i64, time_ns: i64) -> Result<()> { | ||
let conn_info = req.connection_info(); | ||
let Some(addr) = conn_info.realip_remote_addr() else { | ||
return Ok(()); | ||
}; | ||
let today = OffsetDateTime::now_utc().date().to_string(); | ||
CONN.with(|conn| { | ||
match summary::select(&today, &addr, endpoint_id, &conn)? { | ||
Some(entry) => summary::update( | ||
entry.id, | ||
entry.reqests + 1, | ||
entry.entities + entities, | ||
entry.time_ns + time_ns, | ||
&conn, | ||
), | ||
None => summary::insert(&today, &addr, endpoint_id, 1, entities, time_ns, &conn), | ||
}?; | ||
Ok(()) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
mod middleware; | ||
pub use middleware::handle_request as middleware; | ||
pub use middleware::RequestExtension; | ||
mod summary; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters