diff --git a/conf/default.env b/conf/default.env index e2d774e..853e80b 100644 --- a/conf/default.env +++ b/conf/default.env @@ -7,7 +7,7 @@ PATREON_ROLE_ID= LOCAL_TIMEZONE= MIN_INTERVAL= PYTHON_LOCATION=/usr/bin/python3 -DONTRUN=web +DONTRUN= SECRET_KEY= REMIND_INTERVAL= @@ -16,3 +16,4 @@ OAUTH2_CLIENT_ID= OAUTH2_CLIENT_SECRET= REPORT_EMAIL= +LOG_TO_DATABASE=1 diff --git a/postman/src/sender.rs b/postman/src/sender.rs index 182d7a5..eb05823 100644 --- a/postman/src/sender.rs +++ b/postman/src/sender.rs @@ -1,3 +1,5 @@ +use std::env; + use chrono::{DateTime, Days, Duration, Months}; use chrono_tz::Tz; use lazy_static::lazy_static; @@ -30,6 +32,7 @@ lazy_static! { Regex::new(r#"<\d+):(?P.+)?>>"#).unwrap(); pub static ref TIMENOW_REGEX: Regex = Regex::new(r#"<(?:\w|/|_)+):(?P.+)?>>"#).unwrap(); + pub static ref LOG_TO_DATABASE: bool = env::var("LOG_TO_DATABASE").map_or(true, |v| v == "1"); } fn fmt_displacement(format: &str, seconds: u64) -> String { @@ -399,8 +402,12 @@ WHERE } if fail_count >= 4 { - error!("Reminder {} failed to update 4 times and so is being deleted", self.id); - + self.log_error( + pool, + "Failed to update 4 times and so is being deleted", + None::<&'static str>, + ) + .await; self.force_delete(pool).await; } else if self.expires.map_or(false, |expires| updated_reminder_time > expires) { self.force_delete(pool).await; @@ -419,6 +426,48 @@ WHERE } } + async fn log_error( + &self, + pool: impl Executor<'_, Database = Database> + Copy, + error: &'static str, + debug_info: Option, + ) { + let message = match debug_info { + Some(info) => format!( + "{} +{:?}", + error, info + ), + + None => error.to_string(), + }; + + error!("[Reminder {}] {}", self.id, message); + + if *LOG_TO_DATABASE { + sqlx::query!( + "INSERT INTO stat (type, reminder_id, message) VALUES ('reminder_failed', ?, ?)", + self.id, + message, + ) + .execute(pool) + .await + .expect("Could not log error to database"); + } + } + + async fn log_success(&self, pool: impl Executor<'_, Database = Database> + Copy) { + if *LOG_TO_DATABASE { + sqlx::query!( + "INSERT INTO stat (type, reminder_id) VALUES ('reminder_sent', ?)", + self.id, + ) + .execute(pool) + .await + .expect("Could not log success to database"); + } + } + async fn force_delete(&self, pool: impl Executor<'_, Database = Database> + Copy) { sqlx::query!("DELETE FROM reminders WHERE `id` = ?", self.id) .execute(pool) @@ -594,50 +643,61 @@ WHERE if let HttpError::UnsuccessfulRequest(http_error) = *error { match http_error.error.code { 10003 => { - error!( - "Reminder {} could not be sent as channel does not exist", - self.id - ); + self.log_error( + pool, + "Could not be sent as channel does not exist", + None::<&'static str>, + ) + .await; self.force_delete(pool).await; } 10004 => { - error!( - "Reminder {} could not be sent as guild does not exist", - self.id - ); + self.log_error( + pool, + "Could not be sent as guild does not exist", + None::<&'static str>, + ) + .await; self.force_delete(pool).await; } 50001 => { - error!( - "Reminder {} could not be sent as permissions are invalid", - self.id - ); + self.log_error( + pool, + "Could not be sent as permissions are invalid", + None::<&'static str>, + ) + .await; self.force_delete(pool).await; } 50007 => { - error!( - "Reminder {} could not be sent as user has DMs disabled", - self.id - ); + self.log_error( + pool, + "Could not be sent as user has DMs disabled", + None::<&'static str>, + ) + .await; self.force_delete(pool).await; } _ => { - error!("HTTP Error sending reminder {}: {:?}", self.id, http_error); + self.log_error( + pool, + "HTTP error sending reminder", + Some(http_error), + ) + .await; self.refresh(pool).await; } } } else { - error!( - "(Likely) a parsing error when sending reminder {}: {:?}", - self.id, error - ); + self.log_error(pool, "(Likely) a parsing error", Some(error)).await; self.refresh(pool).await; } } else { - error!("Non-HTTP Error sending reminder {}: {:?}", self.id, e); + self.log_error(pool, "Non-HTTP error", Some(e)).await; self.refresh(pool).await; } } else { + self.log_success(pool).await; self.refresh(pool).await; } } else {