diff --git a/ee/query-service/app/server.go b/ee/query-service/app/server.go index a604860b701..98193d6eedc 100644 --- a/ee/query-service/app/server.go +++ b/ee/query-service/app/server.go @@ -512,32 +512,29 @@ func extractQueryRangeData(path string, r *http.Request) (map[string]interface{} zap.L().Error("error while matching the trace explorer: ", zap.Error(err)) } - signozMetricsUsed := false - signozLogsUsed := false - signozTracesUsed := false - if postData != nil { + queryInfoResult := telemetry.GetInstance().CheckQueryInfo(postData) - if postData.CompositeQuery != nil { - data["queryType"] = postData.CompositeQuery.QueryType - data["panelType"] = postData.CompositeQuery.PanelType - - signozLogsUsed, signozMetricsUsed, signozTracesUsed = telemetry.GetInstance().CheckSigNozSignals(postData) - } - } - - if signozMetricsUsed || signozLogsUsed || signozTracesUsed { - if signozMetricsUsed { + if (queryInfoResult.MetricsUsed || queryInfoResult.LogsUsed || queryInfoResult.TracesUsed) && (queryInfoResult.FilterApplied) { + if queryInfoResult.MetricsUsed { telemetry.GetInstance().AddActiveMetricsUser() } - if signozLogsUsed { + if queryInfoResult.LogsUsed { telemetry.GetInstance().AddActiveLogsUser() } - if signozTracesUsed { + if queryInfoResult.TracesUsed { telemetry.GetInstance().AddActiveTracesUser() } - data["metricsUsed"] = signozMetricsUsed - data["logsUsed"] = signozLogsUsed - data["tracesUsed"] = signozTracesUsed + data["metricsUsed"] = queryInfoResult.MetricsUsed + data["logsUsed"] = queryInfoResult.LogsUsed + data["tracesUsed"] = queryInfoResult.TracesUsed + data["filterApplied"] = queryInfoResult.FilterApplied + data["groupByApplied"] = queryInfoResult.GroupByApplied + data["aggregateOperator"] = queryInfoResult.AggregateOperator + data["aggregateAttributeKey"] = queryInfoResult.AggregateAttributeKey + data["numberOfQueries"] = queryInfoResult.NumberOfQueries + data["queryType"] = queryInfoResult.QueryType + data["panelType"] = queryInfoResult.PanelType + userEmail, err := baseauth.GetEmailFromJwt(r.Context()) if err == nil { // switch case to set data["screen"] based on the referrer diff --git a/frontend/src/container/LogsExplorerList/index.tsx b/frontend/src/container/LogsExplorerList/index.tsx index dd97916ce69..9fe76a8443d 100644 --- a/frontend/src/container/LogsExplorerList/index.tsx +++ b/frontend/src/container/LogsExplorerList/index.tsx @@ -1,6 +1,7 @@ import './LogsExplorerList.style.scss'; import { Card } from 'antd'; +import logEvent from 'api/common/logEvent'; import LogDetail from 'components/LogDetail'; import { VIEW_TYPES } from 'components/LogDetail/constants'; // components @@ -18,7 +19,7 @@ import { FontSize } from 'container/OptionsMenu/types'; import { useActiveLog } from 'hooks/logs/useActiveLog'; import { useCopyLogLink } from 'hooks/logs/useCopyLogLink'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; -import { memo, useCallback, useMemo, useRef } from 'react'; +import { memo, useCallback, useEffect, useMemo, useRef } from 'react'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; // interfaces import { ILog } from 'types/api/logs/log'; @@ -71,7 +72,13 @@ function LogsExplorerList({ () => convertKeysToColumnFields(options.selectColumns), [options], ); - + useEffect(() => { + if (!isLoading && !isFetching && !isError && logs.length !== 0) { + logEvent('Logs Explorer: Data present', { + panelType: 'LIST', + }); + } + }, [isLoading, isFetching, isError, logs.length]); const getItemContent = useCallback( (_: number, log: ILog): JSX.Element => { if (options.format === 'raw') { diff --git a/frontend/src/container/TimeSeriesView/TimeSeriesView.tsx b/frontend/src/container/TimeSeriesView/TimeSeriesView.tsx index 27814659cc8..34b6dc4032e 100644 --- a/frontend/src/container/TimeSeriesView/TimeSeriesView.tsx +++ b/frontend/src/container/TimeSeriesView/TimeSeriesView.tsx @@ -1,5 +1,6 @@ import './TimeSeriesView.styles.scss'; +import logEvent from 'api/common/logEvent'; import Uplot from 'components/Uplot'; import { QueryParams } from 'constants/query'; import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch'; @@ -120,6 +121,20 @@ function TimeSeriesView({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + if (chartData[0] && chartData[0]?.length !== 0 && !isLoading && !isError) { + if (dataSource === DataSource.TRACES) { + logEvent('Traces Explorer: Data present', { + panelType: 'TIME_SERIES', + }); + } else if (dataSource === DataSource.LOGS) { + logEvent('Logs Explorer: Data present', { + panelType: 'TIME_SERIES', + }); + } + } + }, [isLoading, isError, chartData, dataSource]); + const { timezone } = useTimezone(); const chartOptions = getUPlotChartOptions({ diff --git a/frontend/src/container/TracesExplorer/ListView/index.tsx b/frontend/src/container/TracesExplorer/ListView/index.tsx index 1c8209f709a..55edba3bddf 100644 --- a/frontend/src/container/TracesExplorer/ListView/index.tsx +++ b/frontend/src/container/TracesExplorer/ListView/index.tsx @@ -1,3 +1,4 @@ +import logEvent from 'api/common/logEvent'; import { ResizeTable } from 'components/ResizeTable'; import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { LOCALSTORAGE } from 'constants/localStorage'; @@ -18,7 +19,7 @@ import { getDraggedColumns } from 'hooks/useDragColumns/utils'; import useUrlQueryData from 'hooks/useUrlQueryData'; import { RowData } from 'lib/query/createTableColumnsFromQuery'; import { useTimezone } from 'providers/Timezone'; -import { memo, useCallback, useMemo } from 'react'; +import { memo, useCallback, useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import { DataSource } from 'types/common/queryBuilder'; @@ -145,12 +146,24 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element { [columns, onDragColumns], ); - const isDataPresent = + const isDataAbsent = !isLoading && !isFetching && !isError && transformedQueryTableData.length === 0; + useEffect(() => { + if ( + !isLoading && + !isFetching && + !isError && + transformedQueryTableData.length !== 0 + ) { + logEvent('Traces Explorer: Data present', { + panelType, + }); + } + }, [isLoading, isFetching, isError, transformedQueryTableData, panelType]); return ( {transformedQueryTableData.length !== 0 && ( @@ -168,11 +181,11 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element { )} - {isDataPresent && !isFilterApplied && ( + {isDataAbsent && !isFilterApplied && ( )} - {isDataPresent && isFilterApplied && ( + {isDataAbsent && isFilterApplied && ( )} diff --git a/frontend/src/container/TracesExplorer/TracesView/index.tsx b/frontend/src/container/TracesExplorer/TracesView/index.tsx index 8739a0b8ea7..140692e7b5e 100644 --- a/frontend/src/container/TracesExplorer/TracesView/index.tsx +++ b/frontend/src/container/TracesExplorer/TracesView/index.tsx @@ -1,4 +1,5 @@ import { Typography } from 'antd'; +import logEvent from 'api/common/logEvent'; import { ResizeTable } from 'components/ResizeTable'; import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { QueryParams } from 'constants/query'; @@ -10,7 +11,7 @@ import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { Pagination } from 'hooks/queryPagination'; import useUrlQueryData from 'hooks/useUrlQueryData'; -import { memo, useMemo } from 'react'; +import { memo, useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import { DataSource } from 'types/common/queryBuilder'; @@ -72,6 +73,14 @@ function TracesView({ isFilterApplied }: TracesViewProps): JSX.Element { [responseData], ); + useEffect(() => { + if (!isLoading && !isFetching && !isError && (tableData || []).length !== 0) { + logEvent('Traces Explorer: Data present', { + panelType: 'TRACE', + }); + } + }, [isLoading, isFetching, isError, panelType, tableData]); + return ( {(tableData || []).length !== 0 && ( diff --git a/frontend/src/pages/TracesExplorer/Filter/Filter.tsx b/frontend/src/pages/TracesExplorer/Filter/Filter.tsx index c4ee2dba5a7..6fbbd49191e 100644 --- a/frontend/src/pages/TracesExplorer/Filter/Filter.tsx +++ b/frontend/src/pages/TracesExplorer/Filter/Filter.tsx @@ -11,7 +11,7 @@ import logEvent from 'api/common/logEvent'; import { getMs } from 'container/Trace/Filters/Panel/PanelBody/Duration/util'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; -import { isArray, isEqual } from 'lodash-es'; +import { isArray, isEmpty, isEqual } from 'lodash-es'; import { Dispatch, SetStateAction, @@ -198,7 +198,7 @@ export function Filter(props: FilterProps): JSX.Element { })), }, }; - if (selectedFilters) { + if (!isEmpty(selectedFilters)) { logEvent('Traces Explorer: Sidebar filter used', { selectedFilters, }); diff --git a/go.mod b/go.mod index 5931d118f89..0f0ea1d9070 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/crypto v0.31.0 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 - golang.org/x/net v0.29.0 + golang.org/x/net v0.33.0 golang.org/x/oauth2 v0.23.0 golang.org/x/text v0.21.0 google.golang.org/grpc v1.67.1 diff --git a/go.sum b/go.sum index b97fc0ff95d..06eb093e9c2 100644 --- a/go.sum +++ b/go.sum @@ -1002,8 +1002,8 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/pkg/query-service/app/clickhouseReader/reader.go b/pkg/query-service/app/clickhouseReader/reader.go index 2a1c1f5782d..fab8fe8330e 100644 --- a/pkg/query-service/app/clickhouseReader/reader.go +++ b/pkg/query-service/app/clickhouseReader/reader.go @@ -2640,7 +2640,7 @@ func (r *ClickHouseReader) GetLogsInfoInLastHeartBeatInterval(ctx context.Contex var totalLogLines uint64 - queryStr := fmt.Sprintf("select count() from %s.%s where timestamp > toUnixTimestamp(now()-toIntervalMinute(%d))*1000000000;", r.logsDB, r.logsTable, int(interval.Minutes())) + queryStr := fmt.Sprintf("select count() from %s.%s where timestamp > toUnixTimestamp(now()-toIntervalMinute(%d))*1000000000;", r.logsDB, r.logsTableV2, int(interval.Minutes())) err := r.db.QueryRow(ctx, queryStr).Scan(&totalLogLines) diff --git a/pkg/query-service/app/dashboards/model.go b/pkg/query-service/app/dashboards/model.go index a858df6159c..5e10eb26bd7 100644 --- a/pkg/query-service/app/dashboards/model.go +++ b/pkg/query-service/app/dashboards/model.go @@ -470,7 +470,7 @@ func GetDashboardsInfo(ctx context.Context) (*model.DashboardsInfo, error) { dashboardInfo := countPanelsInDashboard(dashboard.Data) dashboardsInfo.LogsBasedPanels += dashboardInfo.LogsBasedPanels dashboardsInfo.TracesBasedPanels += dashboardInfo.TracesBasedPanels - dashboardsInfo.MetricBasedPanels += dashboardsInfo.MetricBasedPanels + dashboardsInfo.MetricBasedPanels += dashboardInfo.MetricBasedPanels dashboardsInfo.LogsPanelsWithAttrContainsOp += dashboardInfo.LogsPanelsWithAttrContainsOp dashboardsInfo.DashboardsWithLogsChQuery += dashboardInfo.DashboardsWithLogsChQuery dashboardsInfo.DashboardsWithTraceChQuery += dashboardInfo.DashboardsWithTraceChQuery diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index cf8724f78f5..5da9200c0e3 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -4662,8 +4662,8 @@ func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParam userEmail, err := auth.GetEmailFromJwt(r.Context()) if err == nil { - signozLogsUsed, signozMetricsUsed, signozTracesUsed := telemetry.GetInstance().CheckSigNozSignals(queryRangeParams) - if signozLogsUsed || signozMetricsUsed || signozTracesUsed { + queryInfoResult := telemetry.GetInstance().CheckQueryInfo(queryRangeParams) + if queryInfoResult.LogsUsed || queryInfoResult.MetricsUsed || queryInfoResult.TracesUsed { if dashboardMatched { var dashboardID, widgetID string @@ -4689,13 +4689,18 @@ func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParam widgetID = widgetIDMatch[1] } 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, - "dashboardId": dashboardID, - "widgetId": widgetID, + "queryType": queryRangeParams.CompositeQuery.QueryType, + "panelType": queryRangeParams.CompositeQuery.PanelType, + "tracesUsed": queryInfoResult.TracesUsed, + "logsUsed": queryInfoResult.LogsUsed, + "metricsUsed": queryInfoResult.MetricsUsed, + "numberOfQueries": queryInfoResult.NumberOfQueries, + "groupByApplied": queryInfoResult.GroupByApplied, + "aggregateOperator": queryInfoResult.AggregateOperator, + "aggregateAttributeKey": queryInfoResult.AggregateAttributeKey, + "filterApplied": queryInfoResult.FilterApplied, + "dashboardId": dashboardID, + "widgetId": widgetID, }, userEmail, true, false) } if alertMatched { @@ -4712,12 +4717,17 @@ func sendQueryResultEvents(r *http.Request, result []*v3.Result, queryRangeParam alertID = alertIDMatch[1] } 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, - "alertId": alertID, + "queryType": queryRangeParams.CompositeQuery.QueryType, + "panelType": queryRangeParams.CompositeQuery.PanelType, + "tracesUsed": queryInfoResult.TracesUsed, + "logsUsed": queryInfoResult.LogsUsed, + "metricsUsed": queryInfoResult.MetricsUsed, + "numberOfQueries": queryInfoResult.NumberOfQueries, + "groupByApplied": queryInfoResult.GroupByApplied, + "aggregateOperator": queryInfoResult.AggregateOperator, + "aggregateAttributeKey": queryInfoResult.AggregateAttributeKey, + "filterApplied": queryInfoResult.FilterApplied, + "alertId": alertID, }, userEmail, true, false) } } diff --git a/pkg/query-service/app/server.go b/pkg/query-service/app/server.go index 25ea1e8c938..92b01548fff 100644 --- a/pkg/query-service/app/server.go +++ b/pkg/query-service/app/server.go @@ -13,6 +13,7 @@ import ( _ "net/http/pprof" // http profiler "net/url" "os" + "regexp" "strings" "time" @@ -462,12 +463,13 @@ func (lrw *loggingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) } func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface{}, bool) { - pathToExtractBodyFrom := "/api/v3/query_range" + pathToExtractBodyFromV3 := "/api/v3/query_range" + pathToExtractBodyFromV4 := "/api/v4/query_range" data := map[string]interface{}{} var postData *v3.QueryRangeParamsV3 - if path == pathToExtractBodyFrom && (r.Method == "POST") { + if (r.Method == "POST") && ((path == pathToExtractBodyFromV3) || (path == pathToExtractBodyFromV4)) { if r.Body != nil { bodyBytes, err := io.ReadAll(r.Body) if err != nil { @@ -485,34 +487,64 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface return nil, false } - signozMetricsUsed := false - signozLogsUsed := false - signozTracesUsed := false - if postData != nil { + referrer := r.Header.Get("Referer") - if postData.CompositeQuery != nil { - data["queryType"] = postData.CompositeQuery.QueryType - data["panelType"] = postData.CompositeQuery.PanelType - - signozLogsUsed, signozMetricsUsed, signozTracesUsed = telemetry.GetInstance().CheckSigNozSignals(postData) - } + dashboardMatched, err := regexp.MatchString(`/dashboard/[a-zA-Z0-9\-]+/(new|edit)(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the referrer", zap.Error(err)) + } + alertMatched, err := regexp.MatchString(`/alerts/(new|edit)(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the alert: ", zap.Error(err)) + } + logsExplorerMatched, err := regexp.MatchString(`/logs/logs-explorer(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the logs explorer: ", zap.Error(err)) + } + traceExplorerMatched, err := regexp.MatchString(`/traces-explorer(?:\?.*)?$`, referrer) + if err != nil { + zap.L().Error("error while matching the trace explorer: ", zap.Error(err)) } - if signozMetricsUsed || signozLogsUsed || signozTracesUsed { - if signozMetricsUsed { + queryInfoResult := telemetry.GetInstance().CheckQueryInfo(postData) + + if (queryInfoResult.MetricsUsed || queryInfoResult.LogsUsed || queryInfoResult.TracesUsed) && (queryInfoResult.FilterApplied) { + if queryInfoResult.MetricsUsed { telemetry.GetInstance().AddActiveMetricsUser() } - if signozLogsUsed { + if queryInfoResult.LogsUsed { telemetry.GetInstance().AddActiveLogsUser() } - if signozTracesUsed { + if queryInfoResult.TracesUsed { telemetry.GetInstance().AddActiveTracesUser() } - data["metricsUsed"] = signozMetricsUsed - data["logsUsed"] = signozLogsUsed - data["tracesUsed"] = signozTracesUsed + data["metricsUsed"] = queryInfoResult.MetricsUsed + data["logsUsed"] = queryInfoResult.LogsUsed + data["tracesUsed"] = queryInfoResult.TracesUsed + data["filterApplied"] = queryInfoResult.FilterApplied + data["groupByApplied"] = queryInfoResult.GroupByApplied + data["aggregateOperator"] = queryInfoResult.AggregateOperator + data["aggregateAttributeKey"] = queryInfoResult.AggregateAttributeKey + data["numberOfQueries"] = queryInfoResult.NumberOfQueries + data["queryType"] = queryInfoResult.QueryType + data["panelType"] = queryInfoResult.PanelType + userEmail, err := auth.GetEmailFromJwt(r.Context()) if err == nil { + // switch case to set data["screen"] based on the referrer + switch { + case dashboardMatched: + data["screen"] = "panel" + case alertMatched: + data["screen"] = "alert" + case logsExplorerMatched: + data["screen"] = "logs-explorer" + case traceExplorerMatched: + data["screen"] = "traces-explorer" + default: + data["screen"] = "unknown" + return data, true + } telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_API, data, userEmail, true, false) } } diff --git a/pkg/query-service/model/response.go b/pkg/query-service/model/response.go index 740dfa6ceb9..fe8aec6765f 100644 --- a/pkg/query-service/model/response.go +++ b/pkg/query-service/model/response.go @@ -618,6 +618,7 @@ type TagsInfo struct { type AlertsInfo struct { TotalAlerts int `json:"totalAlerts"` + TotalActiveAlerts int `json:"totalActiveAlerts"` LogsBasedAlerts int `json:"logsBasedAlerts"` MetricBasedAlerts int `json:"metricBasedAlerts"` AnomalyBasedAlerts int `json:"anomalyBasedAlerts"` diff --git a/pkg/query-service/rules/db.go b/pkg/query-service/rules/db.go index 3fe8c5cc950..cc7ef81b8a6 100644 --- a/pkg/query-service/rules/db.go +++ b/pkg/query-service/rules/db.go @@ -616,6 +616,9 @@ func (r *ruleDB) GetAlertsInfo(ctx context.Context) (*model.AlertsInfo, error) { } } alertsInfo.TotalAlerts = alertsInfo.TotalAlerts + 1 + if rule.PostableRule.Disabled == false { + alertsInfo.TotalActiveAlerts = alertsInfo.TotalActiveAlerts + 1 + } } alertsInfo.AlertNames = alertNames diff --git a/pkg/query-service/telemetry/telemetry.go b/pkg/query-service/telemetry/telemetry.go index 8f6cc023334..01cefe3a69f 100644 --- a/pkg/query-service/telemetry/telemetry.go +++ b/pkg/query-service/telemetry/telemetry.go @@ -82,6 +82,19 @@ var OSS_EVENTS_LIST = map[string]struct{}{ TELEMETRY_LICENSE_ACT_FAILED: {}, } +type QueryInfoResult struct { + LogsUsed bool + MetricsUsed bool + TracesUsed bool + FilterApplied bool + GroupByApplied bool + AggregateOperator v3.AggregateOperator + AggregateAttributeKey string + QueryType v3.QueryType + PanelType v3.PanelType + NumberOfQueries int +} + const api_key = "9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr" const IP_NOT_FOUND_PLACEHOLDER = "NA" @@ -107,43 +120,54 @@ func (a *Telemetry) IsSampled() bool { } -func (telemetry *Telemetry) CheckSigNozSignals(postData *v3.QueryRangeParamsV3) (bool, bool, bool) { - signozLogsUsed := false - signozMetricsUsed := false - signozTracesUsed := false +func (telemetry *Telemetry) CheckQueryInfo(postData *v3.QueryRangeParamsV3) QueryInfoResult { + queryInfoResult := QueryInfoResult{} + if postData != nil && postData.CompositeQuery != nil { + queryInfoResult.PanelType = postData.CompositeQuery.PanelType + queryInfoResult.QueryType = postData.CompositeQuery.QueryType + if postData.CompositeQuery.QueryType == v3.QueryTypeBuilder { + queryInfoResult.NumberOfQueries = len(postData.CompositeQuery.BuilderQueries) + for _, query := range postData.CompositeQuery.BuilderQueries { + if query.DataSource == v3.DataSourceLogs { + queryInfoResult.LogsUsed = true + } else if query.DataSource == v3.DataSourceMetrics { + queryInfoResult.MetricsUsed = true - if postData.CompositeQuery.QueryType == v3.QueryTypeBuilder { - for _, query := range postData.CompositeQuery.BuilderQueries { - if query.DataSource == v3.DataSourceLogs && query.Filters != nil && len(query.Filters.Items) > 0 { - signozLogsUsed = true - } else if query.DataSource == v3.DataSourceMetrics && - !strings.Contains(query.AggregateAttribute.Key, "signoz_") && - len(query.AggregateAttribute.Key) > 0 { - signozMetricsUsed = true - } else if query.DataSource == v3.DataSourceTraces && query.Filters != nil && len(query.Filters.Items) > 0 { - signozTracesUsed = true - } - } - } else if postData.CompositeQuery.QueryType == v3.QueryTypePromQL { - for _, query := range postData.CompositeQuery.PromQueries { - if !strings.Contains(query.Query, "signoz_") && len(query.Query) > 0 { - signozMetricsUsed = true - } - } - } else if postData.CompositeQuery.QueryType == v3.QueryTypeClickHouseSQL { - for _, query := range postData.CompositeQuery.ClickHouseQueries { - if strings.Contains(query.Query, "signoz_metrics") && len(query.Query) > 0 { - signozMetricsUsed = true + } else if query.DataSource == v3.DataSourceTraces { + queryInfoResult.TracesUsed = true + } + if query.Filters != nil && len(query.Filters.Items) > 0 { + queryInfoResult.FilterApplied = true + } + if query.GroupBy != nil && len(query.GroupBy) > 0 { + queryInfoResult.GroupByApplied = true + } + queryInfoResult.AggregateOperator = query.AggregateOperator + if len(query.AggregateAttribute.Key) > 0 && !strings.Contains(query.AggregateAttribute.Key, "signoz_") { + queryInfoResult.AggregateAttributeKey = query.AggregateAttribute.Key + } } - if strings.Contains(query.Query, "signoz_logs") && len(query.Query) > 0 { - signozLogsUsed = true + } else if postData.CompositeQuery.QueryType == v3.QueryTypePromQL { + for _, query := range postData.CompositeQuery.PromQueries { + if !strings.Contains(query.Query, "signoz_") && len(query.Query) > 0 { + queryInfoResult.MetricsUsed = true + } } - if strings.Contains(query.Query, "signoz_traces") && len(query.Query) > 0 { - signozTracesUsed = true + } else if postData.CompositeQuery.QueryType == v3.QueryTypeClickHouseSQL { + for _, query := range postData.CompositeQuery.ClickHouseQueries { + if strings.Contains(query.Query, "signoz_metrics") && len(query.Query) > 0 { + queryInfoResult.MetricsUsed = true + } + if strings.Contains(query.Query, "signoz_logs") && len(query.Query) > 0 { + queryInfoResult.LogsUsed = true + } + if strings.Contains(query.Query, "signoz_traces") && len(query.Query) > 0 { + queryInfoResult.TracesUsed = true + } } } } - return signozLogsUsed, signozMetricsUsed, signozTracesUsed + return queryInfoResult } func (telemetry *Telemetry) AddActiveTracesUser() { @@ -350,6 +374,7 @@ func createTelemetry() { "dashboardWithTraceChQuery": dashboardsInfo.DashboardsWithTraceChQuery, "dashboardNamesWithTraceChQuery": dashboardsInfo.DashboardNamesWithTraceChQuery, "totalAlerts": alertsInfo.TotalAlerts, + "totalActiveAlerts": alertsInfo.TotalActiveAlerts, "alertsWithTSV2": alertsInfo.AlertsWithTSV2, "logsBasedAlerts": alertsInfo.LogsBasedAlerts, "metricBasedAlerts": alertsInfo.MetricBasedAlerts, @@ -383,6 +408,23 @@ func createTelemetry() { telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, dashboardsAlertsData, user.Email, false, false) } } + telemetry.SendIdentityEvent(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, + }) } } } @@ -390,6 +432,16 @@ func createTelemetry() { telemetry.SendEvent(TELEMETRY_EVENT_DASHBOARDS_ALERTS, map[string]interface{}{"error": err.Error()}, "", true, false) } + if totalLogs > 0 { + telemetry.SendIdentityEvent(map[string]interface{}{"sent_logs": true}) + } + if totalSpans > 0 { + telemetry.SendIdentityEvent(map[string]interface{}{"sent_traces": true}) + } + if totalSamples > 0 { + telemetry.SendIdentityEvent(map[string]interface{}{"sent_metrics": true}) + } + getDistributedInfoInLastHeartBeatInterval, _ := telemetry.reader.GetDistributedInfoInLastHeartBeatInterval(ctx) telemetry.SendEvent(TELEMETRY_EVENT_DISTRIBUTED, getDistributedInfoInLastHeartBeatInterval, "", true, false) } @@ -518,6 +570,42 @@ func (a *Telemetry) IdentifyUser(user *model.User) { } } +func (a *Telemetry) SendIdentityEvent(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.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 + a.ossOperator.Enqueue(analytics.Group{ + UserId: a.ipAddress, + GroupId: a.getCompanyDomain(), + Traits: traits, + }) + } +} + func (a *Telemetry) SetUserEmail(email string) { a.userEmail = email }