chore: update telemetry events (#6804)

This commit is contained in:
Vishal Sharma 2025-01-14 01:03:12 +05:30 committed by GitHub
parent d5b847c091
commit a60371fb80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 270 additions and 95 deletions

View File

@ -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

View File

@ -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') {

View File

@ -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({

View File

@ -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 (
<Container>
{transformedQueryTableData.length !== 0 && (
@ -168,11 +181,11 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
<TracesLoading />
)}
{isDataPresent && !isFilterApplied && (
{isDataAbsent && !isFilterApplied && (
<NoLogs dataSource={DataSource.TRACES} />
)}
{isDataPresent && isFilterApplied && (
{isDataAbsent && isFilterApplied && (
<EmptyLogsSearch dataSource={DataSource.TRACES} panelType="LIST" />
)}

View File

@ -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 (
<Container>
{(tableData || []).length !== 0 && (

View File

@ -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,
});

View File

@ -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)

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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"`

View File

@ -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

View File

@ -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 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
}
}
}
} 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.QueryTypePromQL {
for _, query := range postData.CompositeQuery.PromQueries {
if !strings.Contains(query.Query, "signoz_") && len(query.Query) > 0 {
queryInfoResult.MetricsUsed = 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
}
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
} 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
}