From 5d88dbc92ce470c951717debe246e182b3fe5656 Mon Sep 17 00:00:00 2001 From: Sampras Lopes Date: Mon, 16 Oct 2023 18:20:23 +0530 Subject: [PATCH] feat(events): add basic event handler to collect application events (#2602) --- crates/router/src/events.rs | 25 ++++++++++++++++++++++++ crates/router/src/events/event_logger.rs | 15 ++++++++++++++ crates/router/src/lib.rs | 1 + crates/router/src/routes/app.rs | 13 +++++++++++- 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 crates/router/src/events.rs create mode 100644 crates/router/src/events/event_logger.rs diff --git a/crates/router/src/events.rs b/crates/router/src/events.rs new file mode 100644 index 000000000000..f573a4970b25 --- /dev/null +++ b/crates/router/src/events.rs @@ -0,0 +1,25 @@ +use serde::Serialize; + +pub mod event_logger; + +pub trait EventHandler: Sync + Send + dyn_clone::DynClone { + fn log_event(&self, event: T, previous: Option); +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum EventType { + PaymentIntent, + PaymentAttempt, + Refund, + ApiLogs, +} + +pub trait Event +where + Self: Serialize, +{ + fn event_type() -> EventType; + + fn key(&self) -> String; +} diff --git a/crates/router/src/events/event_logger.rs b/crates/router/src/events/event_logger.rs new file mode 100644 index 000000000000..d8254b2cc4e9 --- /dev/null +++ b/crates/router/src/events/event_logger.rs @@ -0,0 +1,15 @@ +use super::{Event, EventHandler}; +use crate::services::logger; + +#[derive(Clone, Debug, Default)] +pub struct EventLogger {} + +impl EventHandler for EventLogger { + fn log_event(&self, event: T, previous: Option) { + if let Some(prev) = previous { + logger::info!(previous = ?serde_json::to_string(&prev).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), current = ?serde_json::to_string(&event).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), event_type =? T::event_type(), event_id =? event.key(), log_type = "event"); + } else { + logger::info!(current = ?serde_json::to_string(&event).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), event_type =? T::event_type(), event_id =? event.key(), log_type = "event"); + } + } +} diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index 5cea2a012335..11efec64055b 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -15,6 +15,7 @@ pub(crate) mod macros; pub mod routes; pub mod workflows; +pub mod events; pub mod middleware; pub mod openapi; pub mod services; diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index 7f18220438c4..5ebafe9a66e0 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -25,15 +25,17 @@ use super::{ephemeral_key::*, payment_methods::*, webhooks::*}; use crate::{ configs::settings, db::{StorageImpl, StorageInterface}, + events::{event_logger::EventLogger, EventHandler}, routes::cards_info::card_iin_info, services::get_store, }; #[derive(Clone)] -pub struct AppState { +pub struct AppStateBase { pub flow_name: String, pub store: Box, pub conf: Arc, + pub event_handler: E, #[cfg(feature = "email")] pub email_client: Arc, #[cfg(feature = "kms")] @@ -41,6 +43,8 @@ pub struct AppState { pub api_client: Box, } +pub type AppState = AppStateBase; + impl scheduler::SchedulerAppState for AppState { fn get_db(&self) -> Box { self.store.get_scheduler_db() @@ -48,8 +52,10 @@ impl scheduler::SchedulerAppState for AppState { } pub trait AppStateInfo { + type Event: EventHandler; fn conf(&self) -> settings::Settings; fn store(&self) -> Box; + fn event_handler(&self) -> &Self::Event; #[cfg(feature = "email")] fn email_client(&self) -> Arc; fn add_request_id(&mut self, request_id: Option); @@ -59,6 +65,7 @@ pub trait AppStateInfo { } impl AppStateInfo for AppState { + type Event = EventLogger; fn conf(&self) -> settings::Settings { self.conf.as_ref().to_owned() } @@ -69,6 +76,9 @@ impl AppStateInfo for AppState { fn email_client(&self) -> Arc { self.email_client.to_owned() } + fn event_handler(&self) -> &Self::Event { + &self.event_handler + } fn add_request_id(&mut self, request_id: Option) { self.api_client.add_request_id(request_id); } @@ -137,6 +147,7 @@ impl AppState { #[cfg(feature = "kms")] kms_secrets: Arc::new(kms_secrets), api_client, + event_handler: EventLogger::default(), } }