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["queryType"] = postData.CompositeQuery.QueryType
|
||||||
data["panelType"] = postData.CompositeQuery.PanelType
|
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)
|
zap.S().Debug("Error in processing sql query: ", err)
|
||||||
return &dashboardsInfo, err
|
return &dashboardsInfo, err
|
||||||
}
|
}
|
||||||
|
totalDashboardsWithPanelAndName := 0
|
||||||
for _, dashboard := range dashboardsData {
|
for _, dashboard := range dashboardsData {
|
||||||
|
if isDashboardWithPanelAndName(dashboard.Data) {
|
||||||
|
totalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName + 1
|
||||||
|
}
|
||||||
dashboardsInfo = countPanelsInDashboard(dashboard.Data)
|
dashboardsInfo = countPanelsInDashboard(dashboard.Data)
|
||||||
}
|
}
|
||||||
dashboardsInfo.TotalDashboards = len(dashboardsData)
|
dashboardsInfo.TotalDashboards = len(dashboardsData)
|
||||||
|
dashboardsInfo.TotalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName
|
||||||
return &dashboardsInfo, nil
|
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 {
|
func countPanelsInDashboard(data map[string]interface{}) model.DashboardsInfo {
|
||||||
var logsPanelCount, tracesPanelCount, metricsPanelCount int
|
var logsPanelCount, tracesPanelCount, metricsPanelCount int
|
||||||
// totalPanels := 0
|
// totalPanels := 0
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -3332,6 +3333,7 @@ func (aH *APIHandler) queryRangeV3(ctx context.Context, queryRangeParams *v3.Que
|
|||||||
|
|
||||||
applyMetricLimit(result, queryRangeParams)
|
applyMetricLimit(result, queryRangeParams)
|
||||||
|
|
||||||
|
sendQueryResultEvents(r, result, queryRangeParams)
|
||||||
// only adding applyFunctions instead of postProcess since experssion are
|
// only adding applyFunctions instead of postProcess since experssion are
|
||||||
// are executed in clickhouse directly and we wanted to add support for timeshift
|
// are executed in clickhouse directly and we wanted to add support for timeshift
|
||||||
if queryRangeParams.CompositeQuery.QueryType == v3.QueryTypeBuilder {
|
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.
|
// 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 {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
resp.ContextTimeout = true
|
resp.ContextTimeout = true
|
||||||
@ -3355,6 +3357,50 @@ func (aH *APIHandler) queryRangeV3(ctx context.Context, queryRangeParams *v3.Que
|
|||||||
aH.Respond(w, resp)
|
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) {
|
func (aH *APIHandler) QueryRangeV3(w http.ResponseWriter, r *http.Request) {
|
||||||
queryRangeParams, apiErrorObj := ParseQueryRangeParams(r)
|
queryRangeParams, apiErrorObj := ParseQueryRangeParams(r)
|
||||||
|
|
||||||
@ -3513,7 +3559,7 @@ func (aH *APIHandler) queryRangeV4(ctx context.Context, queryRangeParams *v3.Que
|
|||||||
RespondError(w, apiErrObj, errQuriesByName)
|
RespondError(w, apiErrObj, errQuriesByName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
sendQueryResultEvents(r, result, queryRangeParams)
|
||||||
resp := v3.QueryRangeResponse{
|
resp := v3.QueryRangeResponse{
|
||||||
Result: result,
|
Result: result,
|
||||||
}
|
}
|
||||||
|
@ -371,7 +371,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
|
|||||||
data["queryType"] = postData.CompositeQuery.QueryType
|
data["queryType"] = postData.CompositeQuery.QueryType
|
||||||
data["panelType"] = postData.CompositeQuery.PanelType
|
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 {
|
type DashboardsInfo struct {
|
||||||
TotalDashboards int `json:"totalDashboards"`
|
TotalDashboards int `json:"totalDashboards"`
|
||||||
LogsBasedPanels int `json:"logsBasedPanels"`
|
TotalDashboardsWithPanelAndName int `json:"totalDashboardsWithPanelAndName"` // dashboards with panel and name without sample title
|
||||||
MetricBasedPanels int `json:"metricBasedPanels"`
|
LogsBasedPanels int `json:"logsBasedPanels"`
|
||||||
TracesBasedPanels int `json:"tracesBasedPanels"`
|
MetricBasedPanels int `json:"metricBasedPanels"`
|
||||||
|
TracesBasedPanels int `json:"tracesBasedPanels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagTelemetryData struct {
|
type TagTelemetryData struct {
|
||||||
|
@ -22,41 +22,45 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TELEMETRY_EVENT_PATH = "API Call"
|
TELEMETRY_EVENT_PATH = "API Call"
|
||||||
TELEMETRY_EVENT_USER = "User"
|
TELEMETRY_EVENT_USER = "User"
|
||||||
TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feedback Submitted"
|
TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feedback Submitted"
|
||||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services"
|
TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services"
|
||||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES_PH = "Number of Services V2"
|
TELEMETRY_EVENT_NUMBER_OF_SERVICES_PH = "Number of Services V2"
|
||||||
TELEMETRY_EVENT_HEART_BEAT = "Heart Beat"
|
TELEMETRY_EVENT_HEART_BEAT = "Heart Beat"
|
||||||
TELEMETRY_EVENT_ORG_SETTINGS = "Org Settings"
|
TELEMETRY_EVENT_ORG_SETTINGS = "Org Settings"
|
||||||
DEFAULT_SAMPLING = 0.1
|
DEFAULT_SAMPLING = 0.1
|
||||||
TELEMETRY_LICENSE_CHECK_FAILED = "License Check Failed"
|
TELEMETRY_LICENSE_CHECK_FAILED = "License Check Failed"
|
||||||
TELEMETRY_LICENSE_UPDATED = "License Updated"
|
TELEMETRY_LICENSE_UPDATED = "License Updated"
|
||||||
TELEMETRY_LICENSE_ACT_FAILED = "License Activation Failed"
|
TELEMETRY_LICENSE_ACT_FAILED = "License Activation Failed"
|
||||||
TELEMETRY_EVENT_ENVIRONMENT = "Environment"
|
TELEMETRY_EVENT_ENVIRONMENT = "Environment"
|
||||||
TELEMETRY_EVENT_LANGUAGE = "Language"
|
TELEMETRY_EVENT_LANGUAGE = "Language"
|
||||||
TELEMETRY_EVENT_SERVICE = "ServiceName"
|
TELEMETRY_EVENT_SERVICE = "ServiceName"
|
||||||
TELEMETRY_EVENT_LOGS_FILTERS = "Logs Filters"
|
TELEMETRY_EVENT_LOGS_FILTERS = "Logs Filters"
|
||||||
TELEMETRY_EVENT_DISTRIBUTED = "Distributed"
|
TELEMETRY_EVENT_DISTRIBUTED = "Distributed"
|
||||||
TELEMETRY_EVENT_QUERY_RANGE_V3 = "Query Range V3 Metadata"
|
TELEMETRY_EVENT_QUERY_RANGE_V3 = "Query Range V3 Metadata"
|
||||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS = "Dashboards/Alerts Info"
|
TELEMETRY_EVENT_DASHBOARDS_ALERTS = "Dashboards/Alerts Info"
|
||||||
TELEMETRY_EVENT_ACTIVE_USER = "Active User"
|
TELEMETRY_EVENT_ACTIVE_USER = "Active User"
|
||||||
TELEMETRY_EVENT_ACTIVE_USER_PH = "Active User V2"
|
TELEMETRY_EVENT_ACTIVE_USER_PH = "Active User V2"
|
||||||
TELEMETRY_EVENT_USER_INVITATION_SENT = "User Invitation Sent"
|
TELEMETRY_EVENT_USER_INVITATION_SENT = "User Invitation Sent"
|
||||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED = "User Invitation Accepted"
|
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED = "User Invitation Accepted"
|
||||||
DEFAULT_CLOUD_EMAIL = "admin@signoz.cloud"
|
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{}{
|
var SAAS_EVENTS_LIST = map[string]struct{}{
|
||||||
TELEMETRY_EVENT_NUMBER_OF_SERVICES: {},
|
TELEMETRY_EVENT_NUMBER_OF_SERVICES: {},
|
||||||
TELEMETRY_EVENT_ACTIVE_USER: {},
|
TELEMETRY_EVENT_ACTIVE_USER: {},
|
||||||
TELEMETRY_EVENT_HEART_BEAT: {},
|
TELEMETRY_EVENT_HEART_BEAT: {},
|
||||||
TELEMETRY_EVENT_LANGUAGE: {},
|
TELEMETRY_EVENT_LANGUAGE: {},
|
||||||
TELEMETRY_EVENT_SERVICE: {},
|
TELEMETRY_EVENT_SERVICE: {},
|
||||||
TELEMETRY_EVENT_ENVIRONMENT: {},
|
TELEMETRY_EVENT_ENVIRONMENT: {},
|
||||||
TELEMETRY_EVENT_USER_INVITATION_SENT: {},
|
TELEMETRY_EVENT_USER_INVITATION_SENT: {},
|
||||||
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED: {},
|
TELEMETRY_EVENT_USER_INVITATION_ACCEPTED: {},
|
||||||
TELEMETRY_EVENT_DASHBOARDS_ALERTS: {},
|
TELEMETRY_EVENT_DASHBOARDS_ALERTS: {},
|
||||||
|
TELEMETRY_EVENT_SUCCESSFUL_DASHBOARD_PANEL_QUERY: {},
|
||||||
|
TELEMETRY_EVENT_SUCCESSFUL_ALERT_QUERY: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
|
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
|
signozLogsUsed := false
|
||||||
signozMetricsUsed := false
|
signozMetricsUsed := false
|
||||||
|
signozTracesUsed := false
|
||||||
|
|
||||||
if postData.CompositeQuery.QueryType == v3.QueryTypeBuilder {
|
if postData.CompositeQuery.QueryType == v3.QueryTypeBuilder {
|
||||||
for _, query := range postData.CompositeQuery.BuilderQueries {
|
for _, query := range postData.CompositeQuery.BuilderQueries {
|
||||||
@ -105,6 +110,8 @@ func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3)
|
|||||||
!strings.Contains(query.AggregateAttribute.Key, "signoz_") &&
|
!strings.Contains(query.AggregateAttribute.Key, "signoz_") &&
|
||||||
len(query.AggregateAttribute.Key) > 0 {
|
len(query.AggregateAttribute.Key) > 0 {
|
||||||
signozMetricsUsed = true
|
signozMetricsUsed = true
|
||||||
|
} else if query.DataSource == v3.DataSourceTraces && len(query.Filters.Items) > 0 {
|
||||||
|
signozTracesUsed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if postData.CompositeQuery.QueryType == v3.QueryTypePromQL {
|
} 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 {
|
if strings.Contains(query.Query, "signoz_metrics") && len(query.Query) > 0 {
|
||||||
signozMetricsUsed = true
|
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() {
|
func (telemetry *Telemetry) AddActiveTracesUser() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user