From 819428ad099295eb6693c5d8cf0eae98d1d4e2b3 Mon Sep 17 00:00:00 2001 From: Vishal Sharma Date: Fri, 7 Mar 2025 00:23:47 +0530 Subject: [PATCH] chore: add identify and group event support to /event API (#7219) * chore: add identify and group event support to /event API * chore: minor refactor --- pkg/query-service/app/http_handler.go | 9 +++- pkg/query-service/app/parser.go | 7 ++- pkg/query-service/model/queryParams.go | 14 ++++++ pkg/query-service/telemetry/telemetry.go | 58 +++++++++++++++++++----- 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index d6e293fe97..066874966f 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -1664,7 +1664,14 @@ func (aH *APIHandler) registerEvent(w http.ResponseWriter, r *http.Request) { } claims, ok := authtypes.ClaimsFromContext(r.Context()) if ok { - telemetry.GetInstance().SendEvent(request.EventName, request.Attributes, claims.Email, request.RateLimited, true) + switch request.EventType { + case model.TrackEvent: + telemetry.GetInstance().SendEvent(request.EventName, request.Attributes, claims.Email, request.RateLimited, true) + case model.GroupEvent: + telemetry.GetInstance().SendGroupEvent(request.Attributes) + case model.IdentifyEvent: + telemetry.GetInstance().SendIdentifyEvent(request.Attributes) + } aH.WriteJSON(w, r, map[string]string{"data": "Event Processed Successfully"}) } else { RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil) diff --git a/pkg/query-service/app/parser.go b/pkg/query-service/app/parser.go index 936a38a798..14029d5d94 100644 --- a/pkg/query-service/app/parser.go +++ b/pkg/query-service/app/parser.go @@ -68,7 +68,12 @@ func parseRegisterEventRequest(r *http.Request) (*model.RegisterEventParams, err if err != nil { return nil, err } - if postData.EventName == "" { + // Validate the event type + if !postData.EventType.IsValid() { + return nil, errors.New("eventType param missing/incorrect in query") + } + + if postData.EventType == model.TrackEvent && postData.EventName == "" { return nil, errors.New("eventName param missing in query") } diff --git a/pkg/query-service/model/queryParams.go b/pkg/query-service/model/queryParams.go index e2717fbd87..b62492b0f8 100644 --- a/pkg/query-service/model/queryParams.go +++ b/pkg/query-service/model/queryParams.go @@ -50,7 +50,21 @@ type GetTopOperationsParams struct { Limit int `json:"limit"` } +type EventType string + +const ( + TrackEvent EventType = "track" + IdentifyEvent EventType = "identify" + GroupEvent EventType = "group" +) + +// IsValid checks if the EventType is one of the valid values +func (e EventType) IsValid() bool { + return e == TrackEvent || e == IdentifyEvent || e == GroupEvent +} + type RegisterEventParams struct { + EventType EventType `json:"eventType"` EventName string `json:"eventName"` Attributes map[string]interface{} `json:"attributes"` RateLimited bool `json:"rateLimited"` diff --git a/pkg/query-service/telemetry/telemetry.go b/pkg/query-service/telemetry/telemetry.go index a3f36850cd..183127c07b 100644 --- a/pkg/query-service/telemetry/telemetry.go +++ b/pkg/query-service/telemetry/telemetry.go @@ -409,7 +409,24 @@ func createTelemetry() { telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, dashboardsAlertsData, user.Email, false, false) } } - telemetry.SendIdentityEvent(map[string]interface{}{ + telemetry.SendIdentifyEvent(map[string]interface{}{ + "total_logs": totalLogs, + "total_traces": totalSpans, + "total_metrics": totalSamples, + "total_users": userCount, + "total_channels": alertsInfo.TotalChannels, + "total_dashboards_with_panel": dashboardsInfo.TotalDashboardsWithPanelAndName, + "total_saved_views": savedViewsInfo.TotalSavedViews, + "total_active_alerts": alertsInfo.TotalActiveAlerts, + "total_traces_based_alerts": alertsInfo.TracesBasedAlerts, + "total_logs_based_alerts": alertsInfo.LogsBasedAlerts, + "total_metric_based_alerts": alertsInfo.MetricBasedAlerts, + "total_anomaly_based_alerts": alertsInfo.AnomalyBasedAlerts, + "total_metrics_based_panels": dashboardsInfo.MetricBasedPanels, + "total_logs_based_panels": dashboardsInfo.LogsBasedPanels, + "total_traces_based_panels": dashboardsInfo.TracesBasedPanels, + }) + telemetry.SendGroupEvent(map[string]interface{}{ "total_logs": totalLogs, "total_traces": totalSpans, "total_metrics": totalSamples, @@ -434,13 +451,16 @@ func createTelemetry() { } if totalLogs > 0 { - telemetry.SendIdentityEvent(map[string]interface{}{"sent_logs": true}) + telemetry.SendIdentifyEvent(map[string]interface{}{"sent_logs": true}) + telemetry.SendGroupEvent(map[string]interface{}{"sent_logs": true}) } if totalSpans > 0 { - telemetry.SendIdentityEvent(map[string]interface{}{"sent_traces": true}) + telemetry.SendIdentifyEvent(map[string]interface{}{"sent_traces": true}) + telemetry.SendGroupEvent(map[string]interface{}{"sent_traces": true}) } if totalSamples > 0 { - telemetry.SendIdentityEvent(map[string]interface{}{"sent_metrics": true}) + telemetry.SendIdentifyEvent(map[string]interface{}{"sent_metrics": true}) + telemetry.SendGroupEvent(map[string]interface{}{"sent_metrics": true}) } getDistributedInfoInLastHeartBeatInterval, _ := telemetry.reader.GetDistributedInfoInLastHeartBeatInterval(ctx) @@ -571,7 +591,7 @@ func (a *Telemetry) IdentifyUser(user *types.User) { } } -func (a *Telemetry) SendIdentityEvent(data map[string]interface{}) { +func (a *Telemetry) SendIdentifyEvent(data map[string]interface{}) { if !a.isTelemetryEnabled() || a.isTelemetryAnonymous() { return @@ -582,23 +602,37 @@ func (a *Telemetry) SendIdentityEvent(data map[string]interface{}) { traits.Set(k, v) } if a.saasOperator != nil { - a.saasOperator.Enqueue(analytics.Identify{ UserId: a.GetUserEmail(), Traits: traits, }) - a.saasOperator.Enqueue(analytics.Group{ - UserId: a.userEmail, - GroupId: a.getCompanyDomain(), - Traits: traits, - }) } if a.ossOperator != nil { a.ossOperator.Enqueue(analytics.Identify{ UserId: a.ipAddress, Traits: traits, }) - // Updating a groups properties + } +} + +func (a *Telemetry) SendGroupEvent(data map[string]interface{}) { + + if !a.isTelemetryEnabled() || a.isTelemetryAnonymous() { + return + } + traits := analytics.NewTraits() + + for k, v := range data { + traits.Set(k, v) + } + if a.saasOperator != nil { + a.saasOperator.Enqueue(analytics.Group{ + UserId: a.GetUserEmail(), + GroupId: a.getCompanyDomain(), + Traits: traits, + }) + } + if a.ossOperator != nil { a.ossOperator.Enqueue(analytics.Group{ UserId: a.ipAddress, GroupId: a.getCompanyDomain(),