mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-10 04:49:02 +08:00
chore: extract dashboard/alert query info and send event (#4665)
* chore: extract dashboard/alert query info and send event * chore: add totalDashboardsWithPanelAndName attribute in event
This commit is contained in:
parent
7c2007faa3
commit
4b4008642d
@ -424,7 +424,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
|
||||
data["queryType"] = postData.CompositeQuery.QueryType
|
||||
data["panelType"] = postData.CompositeQuery.PanelType
|
||||
|
||||
signozLogsUsed, signozMetricsUsed = telemetry.GetInstance().CheckSigNozSignals(postData)
|
||||
signozLogsUsed, signozMetricsUsed, _ = telemetry.GetInstance().CheckSigNozSignals(postData)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3480,14 +3480,37 @@ func (r *ClickHouseReader) GetDashboardsInfo(ctx context.Context) (*model.Dashbo
|
||||
zap.S().Debug("Error in processing sql query: ", err)
|
||||
return &dashboardsInfo, err
|
||||
}
|
||||
totalDashboardsWithPanelAndName := 0
|
||||
for _, dashboard := range dashboardsData {
|
||||
if isDashboardWithPanelAndName(dashboard.Data) {
|
||||
totalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName + 1
|
||||
}
|
||||
dashboardsInfo = countPanelsInDashboard(dashboard.Data)
|
||||
}
|
||||
dashboardsInfo.TotalDashboards = len(dashboardsData)
|
||||
|
||||
dashboardsInfo.TotalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName
|
||||
return &dashboardsInfo, nil
|
||||
}
|
||||
|
||||
func isDashboardWithPanelAndName(data map[string]interface{}) bool {
|
||||
isDashboardName := false
|
||||
isDashboardWithPanelAndName := false
|
||||
if data != nil && data["title"] != nil && data["widgets"] != nil {
|
||||
title, ok := data["title"].(string)
|
||||
if ok && title != "Sample Title" {
|
||||
isDashboardName = true
|
||||
}
|
||||
widgets, ok := data["widgets"].(interface{})
|
||||
if ok && isDashboardName {
|
||||
data, ok := widgets.([]interface{})
|
||||
if ok && len(data) > 0 {
|
||||
isDashboardWithPanelAndName = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isDashboardWithPanelAndName
|
||||
}
|
||||
func countPanelsInDashboard(data map[string]interface{}) model.DashboardsInfo {
|
||||
var logsPanelCount, tracesPanelCount, metricsPanelCount int
|
||||
// totalPanels := 0
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -3332,6 +3333,7 @@ func (aH *APIHandler) queryRangeV3(ctx context.Context, queryRangeParams *v3.Que
|
||||
|
||||
applyMetricLimit(result, queryRangeParams)
|
||||
|
||||
sendQueryResultEvents(r, result, queryRangeParams)
|
||||
// only adding applyFunctions instead of postProcess since experssion are
|
||||
// are executed in clickhouse directly and we wanted to add support for timeshift
|
||||
if queryRangeParams.CompositeQuery.QueryType == v3.QueryTypeBuilder {
|
||||
@ -3343,7 +3345,7 @@ func (aH *APIHandler) queryRangeV3(ctx context.Context, queryRangeParams *v3.Que
|
||||
}
|
||||
|
||||
// This checks if the time for context to complete has exceeded.
|
||||
// it adds flag to notify the user of incomplete respone
|
||||
// it adds flag to notify the user of incomplete response
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resp.ContextTimeout = true
|
||||
@ -3355,6 +3357,50 @@ func (aH *APIHandler) queryRangeV3(ctx context.Context, queryRangeParams *v3.Que
|
||||
aH.Respond(w, resp)
|
||||
}
|
||||
|
||||
func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParams *v3.QueryRangeParamsV3) {
|
||||
referrer := r.Header.Get("Referer")
|
||||
|
||||
dashboardMatched, err := regexp.MatchString(`/dashboard/[a-zA-Z0-9\-]+/(new|edit)(?:\?.*)?$`, referrer)
|
||||
if err != nil {
|
||||
zap.S().Errorf("error while matching the referrer: %v", err)
|
||||
}
|
||||
alertMatched, err := regexp.MatchString(`/alerts/(new|edit)(?:\?.*)?$`, referrer)
|
||||
if err != nil {
|
||||
zap.S().Errorf("error while matching the referrer: %v", err)
|
||||
}
|
||||
|
||||
if alertMatched || dashboardMatched {
|
||||
|
||||
if len(result) > 0 && (len(result[0].Series) > 0 || len(result[0].List) > 0) {
|
||||
|
||||
userEmail, err := auth.GetEmailFromJwt(r.Context())
|
||||
if err == nil {
|
||||
signozLogsUsed, signozMetricsUsed, signozTracesUsed := telemetry.GetInstance().CheckSigNozSignals(queryRangeParams)
|
||||
if signozLogsUsed || signozMetricsUsed || signozTracesUsed {
|
||||
if dashboardMatched {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_SUCCESSFUL_DASHBOARD_PANEL_QUERY, map[string]interface{}{
|
||||
"queryType": queryRangeParams.CompositeQuery.QueryType,
|
||||
"panelType": queryRangeParams.CompositeQuery.PanelType,
|
||||
"tracesUsed": signozTracesUsed,
|
||||
"logsUsed": signozLogsUsed,
|
||||
"metricsUsed": signozMetricsUsed,
|
||||
}, userEmail)
|
||||
}
|
||||
if alertMatched {
|
||||
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_SUCCESSFUL_ALERT_QUERY, map[string]interface{}{
|
||||
"queryType": queryRangeParams.CompositeQuery.QueryType,
|
||||
"panelType": queryRangeParams.CompositeQuery.PanelType,
|
||||
"tracesUsed": signozTracesUsed,
|
||||
"logsUsed": signozLogsUsed,
|
||||
"metricsUsed": signozMetricsUsed,
|
||||
}, userEmail)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (aH *APIHandler) QueryRangeV3(w http.ResponseWriter, r *http.Request) {
|
||||
queryRangeParams, apiErrorObj := ParseQueryRangeParams(r)
|
||||
|
||||
@ -3513,7 +3559,7 @@ func (aH *APIHandler) queryRangeV4(ctx context.Context, queryRangeParams *v3.Que
|
||||
RespondError(w, apiErrObj, errQuriesByName)
|
||||
return
|
||||
}
|
||||
|
||||
sendQueryResultEvents(r, result, queryRangeParams)
|
||||
resp := v3.QueryRangeResponse{
|
||||
Result: result,
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
|
||||
data["queryType"] = postData.CompositeQuery.QueryType
|
||||
data["panelType"] = postData.CompositeQuery.PanelType
|
||||
|
||||
signozLogsUsed, signozMetricsUsed = telemetry.GetInstance().CheckSigNozSignals(postData)
|
||||
signozLogsUsed, signozMetricsUsed, _ = telemetry.GetInstance().CheckSigNozSignals(postData)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,10 +624,11 @@ type AlertsInfo struct {
|
||||
}
|
||||
|
||||
type DashboardsInfo struct {
|
||||
TotalDashboards int `json:"totalDashboards"`
|
||||
LogsBasedPanels int `json:"logsBasedPanels"`
|
||||
MetricBasedPanels int `json:"metricBasedPanels"`
|
||||
TracesBasedPanels int `json:"tracesBasedPanels"`
|
||||
TotalDashboards int `json:"totalDashboards"`
|
||||
TotalDashboardsWithPanelAndName int `json:"totalDashboardsWithPanelAndName"` // dashboards with panel and name without sample title
|
||||
LogsBasedPanels int `json:"logsBasedPanels"`
|
||||
MetricBasedPanels int `json:"metricBasedPanels"`
|
||||
TracesBasedPanels int `json:"tracesBasedPanels"`
|
||||
}
|
||||
|
||||
type TagTelemetryData struct {
|
||||
|
@ -22,41 +22,45 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TELEMETRY_EVENT_PATH = "API Call"
|
||||
TELEMETRY_EVENT_USER = "User"
|
||||
TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feedback Submitted"
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services"
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES_PH = "Number of Services V2"
|
||||
TELEMETRY_EVENT_HEART_BEAT = "Heart Beat"
|
||||
TELEMETRY_EVENT_ORG_SETTINGS = "Org Settings"
|
||||
DEFAULT_SAMPLING = 0.1
|
||||
TELEMETRY_LICENSE_CHECK_FAILED = "License Check Failed"
|
||||
TELEMETRY_LICENSE_UPDATED = "License Updated"
|
||||
TELEMETRY_LICENSE_ACT_FAILED = "License Activation Failed"
|
||||
TELEMETRY_EVENT_ENVIRONMENT = "Environment"
|
||||
TELEMETRY_EVENT_LANGUAGE = "Language"
|
||||
TELEMETRY_EVENT_SERVICE = "ServiceName"
|
||||
TELEMETRY_EVENT_LOGS_FILTERS = "Logs Filters"
|
||||
TELEMETRY_EVENT_DISTRIBUTED = "Distributed"
|
||||
TELEMETRY_EVENT_QUERY_RANGE_V3 = "Query Range V3 Metadata"
|
||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS = "Dashboards/Alerts Info"
|
||||
TELEMETRY_EVENT_ACTIVE_USER = "Active User"
|
||||
TELEMETRY_EVENT_ACTIVE_USER_PH = "Active User V2"
|
||||
TELEMETRY_EVENT_USER_INVITATION_SENT = "User Invitation Sent"
|
||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED = "User Invitation Accepted"
|
||||
DEFAULT_CLOUD_EMAIL = "admin@signoz.cloud"
|
||||
TELEMETRY_EVENT_PATH = "API Call"
|
||||
TELEMETRY_EVENT_USER = "User"
|
||||
TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feedback Submitted"
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services"
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES_PH = "Number of Services V2"
|
||||
TELEMETRY_EVENT_HEART_BEAT = "Heart Beat"
|
||||
TELEMETRY_EVENT_ORG_SETTINGS = "Org Settings"
|
||||
DEFAULT_SAMPLING = 0.1
|
||||
TELEMETRY_LICENSE_CHECK_FAILED = "License Check Failed"
|
||||
TELEMETRY_LICENSE_UPDATED = "License Updated"
|
||||
TELEMETRY_LICENSE_ACT_FAILED = "License Activation Failed"
|
||||
TELEMETRY_EVENT_ENVIRONMENT = "Environment"
|
||||
TELEMETRY_EVENT_LANGUAGE = "Language"
|
||||
TELEMETRY_EVENT_SERVICE = "ServiceName"
|
||||
TELEMETRY_EVENT_LOGS_FILTERS = "Logs Filters"
|
||||
TELEMETRY_EVENT_DISTRIBUTED = "Distributed"
|
||||
TELEMETRY_EVENT_QUERY_RANGE_V3 = "Query Range V3 Metadata"
|
||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS = "Dashboards/Alerts Info"
|
||||
TELEMETRY_EVENT_ACTIVE_USER = "Active User"
|
||||
TELEMETRY_EVENT_ACTIVE_USER_PH = "Active User V2"
|
||||
TELEMETRY_EVENT_USER_INVITATION_SENT = "User Invitation Sent"
|
||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED = "User Invitation Accepted"
|
||||
TELEMETRY_EVENT_SUCCESSFUL_DASHBOARD_PANEL_QUERY = "Successful Dashboard Panel Query"
|
||||
TELEMETRY_EVENT_SUCCESSFUL_ALERT_QUERY = "Successful Alert Query"
|
||||
DEFAULT_CLOUD_EMAIL = "admin@signoz.cloud"
|
||||
)
|
||||
|
||||
var SAAS_EVENTS_LIST = map[string]struct{}{
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES: {},
|
||||
TELEMETRY_EVENT_ACTIVE_USER: {},
|
||||
TELEMETRY_EVENT_HEART_BEAT: {},
|
||||
TELEMETRY_EVENT_LANGUAGE: {},
|
||||
TELEMETRY_EVENT_SERVICE: {},
|
||||
TELEMETRY_EVENT_ENVIRONMENT: {},
|
||||
TELEMETRY_EVENT_USER_INVITATION_SENT: {},
|
||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED: {},
|
||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS: {},
|
||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES: {},
|
||||
TELEMETRY_EVENT_ACTIVE_USER: {},
|
||||
TELEMETRY_EVENT_HEART_BEAT: {},
|
||||
TELEMETRY_EVENT_LANGUAGE: {},
|
||||
TELEMETRY_EVENT_SERVICE: {},
|
||||
TELEMETRY_EVENT_ENVIRONMENT: {},
|
||||
TELEMETRY_EVENT_USER_INVITATION_SENT: {},
|
||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED: {},
|
||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS: {},
|
||||
TELEMETRY_EVENT_SUCCESSFUL_DASHBOARD_PANEL_QUERY: {},
|
||||
TELEMETRY_EVENT_SUCCESSFUL_ALERT_QUERY: {},
|
||||
}
|
||||
|
||||
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
|
||||
@ -93,9 +97,10 @@ func (a *Telemetry) IsSampled() bool {
|
||||
|
||||
}
|
||||
|
||||
func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3) (bool, bool) {
|
||||
func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3) (bool, bool, bool) {
|
||||
signozLogsUsed := false
|
||||
signozMetricsUsed := false
|
||||
signozTracesUsed := false
|
||||
|
||||
if postData.CompositeQuery.QueryType == v3.QueryTypeBuilder {
|
||||
for _, query := range postData.CompositeQuery.BuilderQueries {
|
||||
@ -105,6 +110,8 @@ func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3)
|
||||
!strings.Contains(query.AggregateAttribute.Key, "signoz_") &&
|
||||
len(query.AggregateAttribute.Key) > 0 {
|
||||
signozMetricsUsed = true
|
||||
} else if query.DataSource == v3.DataSourceTraces && len(query.Filters.Items) > 0 {
|
||||
signozTracesUsed = true
|
||||
}
|
||||
}
|
||||
} else if postData.CompositeQuery.QueryType == v3.QueryTypePromQL {
|
||||
@ -118,9 +125,15 @@ func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3)
|
||||
if strings.Contains(query.Query, "signoz_metrics") && len(query.Query) > 0 {
|
||||
signozMetricsUsed = true
|
||||
}
|
||||
if strings.Contains(query.Query, "signoz_logs") && len(query.Query) > 0 {
|
||||
signozLogsUsed = true
|
||||
}
|
||||
if strings.Contains(query.Query, "signoz_traces") && len(query.Query) > 0 {
|
||||
signozTracesUsed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return signozLogsUsed, signozMetricsUsed
|
||||
return signozLogsUsed, signozMetricsUsed, signozTracesUsed
|
||||
}
|
||||
|
||||
func (telemetry *Telemetry) AddActiveTracesUser() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user