mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
feat(analytics): Add Clickhouse based analytics (#2988)
Co-authored-by: harsh_sharma_juspay <harsh.sharma@juspay.in> Co-authored-by: Ivor Dsouza <ivor.dsouza@juspay.in> Co-authored-by: Chethan Rao <70657455+Chethan-rao@users.noreply.github.com> Co-authored-by: nain-F49FF806 <126972030+nain-F49FF806@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: akshay.s <akshay.s@juspay.in> Co-authored-by: Gnanasundari24 <118818938+Gnanasundari24@users.noreply.github.com>
This commit is contained in:
@ -24,6 +24,7 @@ use crate::{
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ApiEvent {
|
||||
merchant_id: Option<String>,
|
||||
api_flow: String,
|
||||
created_at_timestamp: i128,
|
||||
request_id: String,
|
||||
@ -40,11 +41,13 @@ pub struct ApiEvent {
|
||||
#[serde(flatten)]
|
||||
event_type: ApiEventsType,
|
||||
hs_latency: Option<u128>,
|
||||
http_method: Option<String>,
|
||||
}
|
||||
|
||||
impl ApiEvent {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
merchant_id: Option<String>,
|
||||
api_flow: &impl FlowMetric,
|
||||
request_id: &RequestId,
|
||||
latency: u128,
|
||||
@ -56,8 +59,10 @@ impl ApiEvent {
|
||||
error: Option<serde_json::Value>,
|
||||
event_type: ApiEventsType,
|
||||
http_req: &HttpRequest,
|
||||
http_method: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
merchant_id,
|
||||
api_flow: api_flow.to_string(),
|
||||
created_at_timestamp: OffsetDateTime::now_utc().unix_timestamp_nanos() / 1_000_000,
|
||||
request_id: request_id.as_hyphenated().to_string(),
|
||||
@ -78,6 +83,7 @@ impl ApiEvent {
|
||||
url_path: http_req.path().to_string(),
|
||||
event_type,
|
||||
hs_latency,
|
||||
http_method,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,6 @@ pub struct EventLogger {}
|
||||
impl EventHandler for EventLogger {
|
||||
#[track_caller]
|
||||
fn log_event(&self, event: RawEvent) {
|
||||
logger::info!(event = ?serde_json::to_string(&event.payload).unwrap_or(r#"{ "error": "Serialization failed" }"#.to_string()), event_type =? event.event_type, event_id =? event.key, log_type = "event");
|
||||
logger::info!(event = ?event.payload.to_string(), event_type =? event.event_type, event_id =? event.key, log_type = "event");
|
||||
}
|
||||
}
|
||||
|
||||
29
crates/router/src/events/kafka_handler.rs
Normal file
29
crates/router/src/events/kafka_handler.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use router_env::tracing;
|
||||
|
||||
use super::{EventHandler, RawEvent};
|
||||
use crate::{
|
||||
db::MQResult,
|
||||
services::kafka::{KafkaError, KafkaMessage, KafkaProducer},
|
||||
};
|
||||
impl EventHandler for KafkaProducer {
|
||||
fn log_event(&self, event: RawEvent) {
|
||||
let topic = self.get_topic(event.event_type);
|
||||
if let Err(er) = self.log_kafka_event(topic, &event) {
|
||||
tracing::error!("Failed to log event to kafka: {:?}", er);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KafkaMessage for RawEvent {
|
||||
fn key(&self) -> String {
|
||||
self.key.clone()
|
||||
}
|
||||
|
||||
fn value(&self) -> MQResult<Vec<u8>> {
|
||||
// Add better error logging here
|
||||
serde_json::to_vec(&self.payload)
|
||||
.into_report()
|
||||
.change_context(KafkaError::GenericError)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user