mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-10 01:59:01 +08:00
feat: add events API (#4761)
This commit is contained in:
parent
990fc83269
commit
da4a6266c5
@ -445,7 +445,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
|
||||
data["tracesUsed"] = signozTracesUsed
|
||||
userEmail, err := baseauth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
return data, true
|
||||
@ -488,7 +488,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
|
||||
if _, ok := telemetry.EnabledPaths()[path]; ok {
|
||||
userEmail, err := baseauth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ func (lm *Manager) Validate(ctx context.Context) (reterr error) {
|
||||
zap.L().Error("License validation completed with error", zap.Error(reterr))
|
||||
atomic.AddUint64(&lm.failedAttempts, 1)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_LICENSE_CHECK_FAILED,
|
||||
map[string]interface{}{"err": reterr.Error()}, "")
|
||||
map[string]interface{}{"err": reterr.Error()}, "", true, false)
|
||||
} else {
|
||||
zap.L().Info("License validation completed with no errors")
|
||||
}
|
||||
@ -263,7 +263,7 @@ func (lm *Manager) Activate(ctx context.Context, key string) (licenseResponse *m
|
||||
userEmail, err := auth.GetEmailFromJwt(ctx)
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_LICENSE_ACT_FAILED,
|
||||
map[string]interface{}{"err": errResponse.Err.Error()}, userEmail)
|
||||
map[string]interface{}{"err": errResponse.Err.Error()}, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -3802,7 +3802,7 @@ func (r *ClickHouseReader) GetLogs(ctx context.Context, params *model.LogsFilter
|
||||
if lenFilters != 0 {
|
||||
userEmail, err := auth.GetEmailFromJwt(ctx)
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3844,7 +3844,7 @@ func (r *ClickHouseReader) TailLogs(ctx context.Context, client *model.LogsTailC
|
||||
if lenFilters != 0 {
|
||||
userEmail, err := auth.GetEmailFromJwt(ctx)
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3936,7 +3936,7 @@ func (r *ClickHouseReader) AggregateLogs(ctx context.Context, params *model.Logs
|
||||
if lenFilters != 0 {
|
||||
userEmail, err := auth.GetEmailFromJwt(ctx)
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_LOGS_FILTERS, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,6 +401,8 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *AuthMiddleware) {
|
||||
router.HandleFunc("/api/v1/explorer/views/{viewId}", am.EditAccess(aH.deleteSavedView)).Methods(http.MethodDelete)
|
||||
|
||||
router.HandleFunc("/api/v1/feedback", am.OpenAccess(aH.submitFeedback)).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/events", am.ViewAccess(aH.registerEvent)).Methods(http.MethodPost)
|
||||
|
||||
// router.HandleFunc("/api/v1/get_percentiles", aH.getApplicationPercentiles).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/services", am.ViewAccess(aH.getServices)).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/services/list", am.ViewAccess(aH.getServicesList)).Methods(http.MethodGet)
|
||||
@ -1502,7 +1504,22 @@ func (aH *APIHandler) submitFeedback(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_INPRODUCT_FEEDBACK, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_INPRODUCT_FEEDBACK, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (aH *APIHandler) registerEvent(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
request, err := parseRegisterEventRequest(r)
|
||||
if aH.HandleError(w, err, http.StatusBadRequest) {
|
||||
return
|
||||
}
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(request.EventName, request.Attributes, userEmail, true, true)
|
||||
aH.WriteJSON(w, r, map[string]string{"data": "Event Processed Successfully"})
|
||||
} else {
|
||||
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1585,7 +1602,7 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_NUMBER_OF_SERVICES, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_NUMBER_OF_SERVICES, data, userEmail, true, false)
|
||||
}
|
||||
|
||||
if (data["number"] != 0) && (data["number"] != telemetry.DEFAULT_NUMBER_OF_SERVICES) {
|
||||
@ -2310,7 +2327,7 @@ func (aH *APIHandler) editOrg(w http.ResponseWriter, r *http.Request) {
|
||||
"organizationName": req.Name,
|
||||
}
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_ORG_SETTINGS, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_ORG_SETTINGS, data, userEmail, true, false)
|
||||
|
||||
aH.WriteJSON(w, r, map[string]string{"data": "org updated successfully"})
|
||||
}
|
||||
@ -3525,7 +3542,7 @@ func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParam
|
||||
"metricsUsed": signozMetricsUsed,
|
||||
"dashboardId": dashboardID,
|
||||
"widgetId": widgetID,
|
||||
}, userEmail)
|
||||
}, userEmail, true, false)
|
||||
}
|
||||
if alertMatched {
|
||||
var alertID string
|
||||
@ -3547,7 +3564,7 @@ func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParam
|
||||
"logsUsed": signozLogsUsed,
|
||||
"metricsUsed": signozMetricsUsed,
|
||||
"alertId": alertID,
|
||||
}, userEmail)
|
||||
}, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,19 @@ func parseGetTopOperationsRequest(r *http.Request) (*model.GetTopOperationsParam
|
||||
return postData, nil
|
||||
}
|
||||
|
||||
func parseRegisterEventRequest(r *http.Request) (*model.RegisterEventParams, error) {
|
||||
var postData *model.RegisterEventParams
|
||||
err := json.NewDecoder(r.Body).Decode(&postData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if postData.EventName == "" {
|
||||
return nil, errors.New("eventName param missing in query")
|
||||
}
|
||||
|
||||
return postData, nil
|
||||
}
|
||||
|
||||
func parseMetricsTime(s string) (time.Time, error) {
|
||||
if t, err := strconv.ParseFloat(s, 64); err == nil {
|
||||
s, ns := math.Modf(t)
|
||||
|
@ -452,7 +452,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
|
||||
data["tracesUsed"] = signozTracesUsed
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
return data, true
|
||||
@ -496,7 +496,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
|
||||
if _, ok := telemetry.EnabledPaths()[path]; ok {
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail, true, false)
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
@ -89,7 +89,7 @@ func Invite(ctx context.Context, req *model.InviteRequest) (*model.InviteRespons
|
||||
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER_INVITATION_SENT, map[string]interface{}{
|
||||
"invited user email": req.Email,
|
||||
}, au.Email)
|
||||
}, au.Email, true, false)
|
||||
|
||||
// send email if SMTP is enabled
|
||||
if os.Getenv("SMTP_ENABLED") == "true" && req.FrontendBaseUrl != "" {
|
||||
@ -404,7 +404,7 @@ func RegisterInvitedUser(ctx context.Context, req *RegisterRequest, nopassword b
|
||||
}
|
||||
|
||||
telemetry.GetInstance().IdentifyUser(user)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER_INVITATION_ACCEPTED, nil, req.Email)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER_INVITATION_ACCEPTED, nil, req.Email, true, false)
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func (mds *ModelDaoSqlite) CreateUser(ctx context.Context,
|
||||
}
|
||||
|
||||
telemetry.GetInstance().IdentifyUser(user)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER, data, user.Email)
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER, data, user.Email, true, false)
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
@ -164,6 +164,11 @@ type GetTopOperationsParams struct {
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
type RegisterEventParams struct {
|
||||
EventName string `json:"eventName"`
|
||||
Attributes map[string]interface{} `json:"attributes"`
|
||||
}
|
||||
|
||||
type GetUsageParams struct {
|
||||
StartTime string
|
||||
EndTime string
|
||||
|
@ -197,7 +197,7 @@ func createTelemetry() {
|
||||
data := map[string]interface{}{}
|
||||
|
||||
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data, "", true, false)
|
||||
|
||||
ticker := time.NewTicker(HEART_BEAT_DURATION)
|
||||
activeUserTicker := time.NewTicker(ACTIVE_USER_DURATION)
|
||||
@ -231,7 +231,12 @@ func createTelemetry() {
|
||||
if (telemetry.activeUser["traces"] != 0) || (telemetry.activeUser["metrics"] != 0) || (telemetry.activeUser["logs"] != 0) {
|
||||
telemetry.activeUser["any"] = 1
|
||||
}
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_ACTIVE_USER, map[string]interface{}{"traces": telemetry.activeUser["traces"], "metrics": telemetry.activeUser["metrics"], "logs": telemetry.activeUser["logs"], "any": telemetry.activeUser["any"]}, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_ACTIVE_USER, map[string]interface{}{
|
||||
"traces": telemetry.activeUser["traces"],
|
||||
"metrics": telemetry.activeUser["metrics"],
|
||||
"logs": telemetry.activeUser["logs"],
|
||||
"any": telemetry.activeUser["any"]},
|
||||
"", true, false)
|
||||
telemetry.activeUser = map[string]int8{"traces": 0, "metrics": 0, "logs": 0, "any": 0}
|
||||
|
||||
case <-ticker.C:
|
||||
@ -239,15 +244,15 @@ func createTelemetry() {
|
||||
tagsInfo, _ := telemetry.reader.GetTagsInfoInLastHeartBeatInterval(context.Background(), HEART_BEAT_DURATION)
|
||||
|
||||
if len(tagsInfo.Env) != 0 {
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_ENVIRONMENT, map[string]interface{}{"value": tagsInfo.Env}, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_ENVIRONMENT, map[string]interface{}{"value": tagsInfo.Env}, "", true, false)
|
||||
}
|
||||
|
||||
for language, _ := range tagsInfo.Languages {
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_LANGUAGE, map[string]interface{}{"language": language}, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_LANGUAGE, map[string]interface{}{"language": language}, "", true, false)
|
||||
}
|
||||
|
||||
for service, _ := range tagsInfo.Services {
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_SERVICE, map[string]interface{}{"serviceName": service}, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_SERVICE, map[string]interface{}{"serviceName": service}, "", true, false)
|
||||
}
|
||||
|
||||
totalSpans, _ := telemetry.reader.GetTotalSpans(context.Background())
|
||||
@ -280,7 +285,7 @@ func createTelemetry() {
|
||||
for key, value := range tsInfo {
|
||||
data[key] = value
|
||||
}
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data, "", true, false)
|
||||
|
||||
alertsInfo, err := telemetry.reader.GetAlertsInfo(context.Background())
|
||||
if err == nil {
|
||||
@ -307,18 +312,18 @@ func createTelemetry() {
|
||||
}
|
||||
// send event only if there are dashboards or alerts or channels
|
||||
if dashboardsInfo.TotalDashboards > 0 || alertsInfo.TotalAlerts > 0 || len(*channels) > 0 || savedViewsInfo.TotalSavedViews > 0 {
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, dashboardsAlertsData, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, dashboardsAlertsData, "", true, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, map[string]interface{}{"error": err.Error()}, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, map[string]interface{}{"error": err.Error()}, "", true, false)
|
||||
}
|
||||
|
||||
getDistributedInfoInLastHeartBeatInterval, _ := telemetry.reader.GetDistributedInfoInLastHeartBeatInterval(context.Background())
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DISTRIBUTED, getDistributedInfoInLastHeartBeatInterval, "")
|
||||
telemetry.SendEvent(TELEMETRY_EVENT_DISTRIBUTED, getDistributedInfoInLastHeartBeatInterval, "", true, false)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -426,7 +431,7 @@ func (a *Telemetry) checkEvents(event string) bool {
|
||||
return sendEvent
|
||||
}
|
||||
|
||||
func (a *Telemetry) SendEvent(event string, data map[string]interface{}, userEmail string, opts ...bool) {
|
||||
func (a *Telemetry) SendEvent(event string, data map[string]interface{}, userEmail string, rateLimitFlag bool, viaEventsAPI bool) {
|
||||
|
||||
// ignore telemetry for default user
|
||||
if userEmail == DEFAULT_CLOUD_EMAIL || a.GetUserEmail() == DEFAULT_CLOUD_EMAIL {
|
||||
@ -436,10 +441,6 @@ func (a *Telemetry) SendEvent(event string, data map[string]interface{}, userEma
|
||||
if userEmail != "" {
|
||||
a.SetUserEmail(userEmail)
|
||||
}
|
||||
rateLimitFlag := true
|
||||
if len(opts) > 0 {
|
||||
rateLimitFlag = opts[0]
|
||||
}
|
||||
|
||||
if !a.isTelemetryEnabled() {
|
||||
return
|
||||
@ -485,7 +486,7 @@ func (a *Telemetry) SendEvent(event string, data map[string]interface{}, userEma
|
||||
// check if event is part of SAAS_EVENTS_LIST
|
||||
_, isSaaSEvent := SAAS_EVENTS_LIST[event]
|
||||
|
||||
if a.saasOperator != nil && a.GetUserEmail() != "" && isSaaSEvent {
|
||||
if a.saasOperator != nil && a.GetUserEmail() != "" && (isSaaSEvent || viaEventsAPI) {
|
||||
a.saasOperator.Enqueue(analytics.Track{
|
||||
Event: event,
|
||||
UserId: a.GetUserEmail(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user