fix: tlemetry for dashboard/alerts/views using contains on attributes (#6034)

* fix: tlemetry for dashboard/alerts/views using contains on attributes

* fix: update how telemetry is collected for logs

* fix: revert constands

* fix: check assertion for operator
This commit is contained in:
Nityananda Gohain 2024-09-20 18:02:33 +05:30 committed by GitHub
parent cb1cd3555b
commit f6d3f95768
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 94 additions and 15 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"regexp"
"slices"
"strings"
"time"
@ -453,7 +454,6 @@ func GetDashboardsInfo(ctx context.Context) (*model.DashboardsInfo, error) {
totalDashboardsWithPanelAndName := 0
var dashboardNames []string
count := 0
logChQueriesCount := 0
for _, dashboard := range dashboardsData {
if isDashboardWithPanelAndName(dashboard.Data) {
totalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName + 1
@ -466,19 +466,18 @@ func GetDashboardsInfo(ctx context.Context) (*model.DashboardsInfo, error) {
dashboardsInfo.LogsBasedPanels += dashboardInfo.LogsBasedPanels
dashboardsInfo.TracesBasedPanels += dashboardInfo.TracesBasedPanels
dashboardsInfo.MetricBasedPanels += dashboardsInfo.MetricBasedPanels
dashboardsInfo.LogsPanelsWithAttrContainsOp += dashboardInfo.LogsPanelsWithAttrContainsOp
dashboardsInfo.DashboardsWithLogsChQuery += dashboardInfo.DashboardsWithLogsChQuery
if isDashboardWithTSV2(dashboard.Data) {
count = count + 1
}
if isDashboardWithLogsClickhouseQuery(dashboard.Data) {
logChQueriesCount = logChQueriesCount + 1
}
// check if dashboard is a has a log operator with contains
}
dashboardsInfo.DashboardNames = dashboardNames
dashboardsInfo.TotalDashboards = len(dashboardsData)
dashboardsInfo.TotalDashboardsWithPanelAndName = totalDashboardsWithPanelAndName
dashboardsInfo.QueriesWithTSV2 = count
dashboardsInfo.DashboardsWithLogsChQuery = logChQueriesCount
return &dashboardsInfo, nil
}
@ -495,8 +494,8 @@ func isDashboardWithLogsClickhouseQuery(data map[string]interface{}) bool {
if err != nil {
return false
}
result := strings.Contains(string(jsonData), "signoz_logs.distributed_logs ") ||
strings.Contains(string(jsonData), "signoz_logs.logs ")
result := strings.Contains(string(jsonData), "signoz_logs.distributed_logs") ||
strings.Contains(string(jsonData), "signoz_logs.logs")
return result
}
@ -532,11 +531,38 @@ func extractDashboardName(data map[string]interface{}) string {
return ""
}
func countPanelsInDashboard(data map[string]interface{}) model.DashboardsInfo {
var logsPanelCount, tracesPanelCount, metricsPanelCount int
func checkLogPanelAttrContains(data map[string]interface{}) int {
var logsPanelsWithAttrContains int
filters, ok := data["filters"].(map[string]interface{})
if ok && filters["items"] != nil {
items, ok := filters["items"].([]interface{})
if ok {
for _, item := range items {
itemMap, ok := item.(map[string]interface{})
if ok {
opStr, ok := itemMap["op"].(string)
if ok {
if slices.Contains([]string{"contains", "ncontains", "like", "nlike"}, opStr) {
// check if it's not body
key, ok := itemMap["key"].(map[string]string)
if ok && key["key"] != "body" {
logsPanelsWithAttrContains++
}
}
}
}
}
}
}
return logsPanelsWithAttrContains
}
func countPanelsInDashboard(inputData map[string]interface{}) model.DashboardsInfo {
var logsPanelCount, tracesPanelCount, metricsPanelCount, logsPanelsWithAttrContains int
var logChQuery bool
// totalPanels := 0
if data != nil && data["widgets"] != nil {
widgets, ok := data["widgets"]
if inputData != nil && inputData["widgets"] != nil {
widgets, ok := inputData["widgets"]
if ok {
data, ok := widgets.([]interface{})
if ok {
@ -559,20 +585,33 @@ func countPanelsInDashboard(data map[string]interface{}) model.DashboardsInfo {
metricsPanelCount++
} else if data["dataSource"] == "logs" {
logsPanelCount++
logsPanelsWithAttrContains += checkLogPanelAttrContains(data)
}
}
}
}
}
} else if ok && query["queryType"] == "clickhouse_sql" && query["clickhouse_sql"] != nil {
if isDashboardWithLogsClickhouseQuery(inputData) {
logChQuery = true
}
}
}
}
}
}
}
logChQueryCount := 0
if logChQuery {
logChQueryCount = 1
}
return model.DashboardsInfo{
LogsBasedPanels: logsPanelCount,
TracesBasedPanels: tracesPanelCount,
MetricBasedPanels: metricsPanelCount,
DashboardsWithLogsChQuery: logChQueryCount,
LogsPanelsWithAttrContainsOp: logsPanelsWithAttrContains,
}
}

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"slices"
"strings"
"time"
@ -247,6 +248,18 @@ func GetSavedViewsInfo(ctx context.Context) (*model.SavedViewsInfo, error) {
savedViewsInfo.TracesSavedViews += 1
} else if view.SourcePage == "logs" {
savedViewsInfo.LogsSavedViews += 1
for _, query := range view.CompositeQuery.BuilderQueries {
if query.Filters != nil {
for _, item := range query.Filters.Items {
if slices.Contains([]string{"contains", "ncontains", "like", "nlike"}, string(item.Operator)) {
if item.Key.Key != "body" {
savedViewsInfo.LogsSavedViewWithContainsOp += 1
}
}
}
}
}
}
}
return &savedViewsInfo, nil

View File

@ -632,12 +632,15 @@ type AlertsInfo struct {
AlertNames []string `json:"alertNames"`
AlertsWithTSV2 int `json:"alertsWithTSv2"`
AlertsWithLogsChQuery int `json:"alertsWithLogsChQuery"`
AlertsWithLogsContainsOp int `json:"alertsWithLogsContainsOp"`
}
type SavedViewsInfo struct {
TotalSavedViews int `json:"totalSavedViews"`
TracesSavedViews int `json:"tracesSavedViews"`
LogsSavedViews int `json:"logsSavedViews"`
LogsSavedViewWithContainsOp int `json:"logsSavedViewWithContainsOp"`
}
type DashboardsInfo struct {
@ -649,6 +652,7 @@ type DashboardsInfo struct {
DashboardNames []string `json:"dashboardNames"`
QueriesWithTSV2 int `json:"queriesWithTSV2"`
DashboardsWithLogsChQuery int `json:"dashboardsWithLogsChQuery"`
LogsPanelsWithAttrContainsOp int `json:"logsPanelsWithAttrContainsOp"`
}
type TagTelemetryData struct {

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"slices"
"strconv"
"strings"
"time"
@ -551,10 +552,6 @@ func (r *ruleDB) GetAlertsInfo(ctx context.Context) (*model.AlertsInfo, error) {
if strings.Contains(alert, "time_series_v2") {
alertsInfo.AlertsWithTSV2 = alertsInfo.AlertsWithTSV2 + 1
}
if strings.Contains(alert, "signoz_logs.distributed_logs") ||
strings.Contains(alert, "signoz_logs.logs") {
alertsInfo.AlertsWithLogsChQuery = alertsInfo.AlertsWithLogsChQuery + 1
}
err = json.Unmarshal([]byte(alert), &rule)
if err != nil {
zap.L().Error("invalid rule data", zap.Error(err))
@ -563,6 +560,29 @@ func (r *ruleDB) GetAlertsInfo(ctx context.Context) (*model.AlertsInfo, error) {
alertNames = append(alertNames, rule.AlertName)
if rule.AlertType == AlertTypeLogs {
alertsInfo.LogsBasedAlerts = alertsInfo.LogsBasedAlerts + 1
if rule.RuleCondition != nil && rule.RuleCondition.CompositeQuery != nil {
if rule.RuleCondition.CompositeQuery.QueryType == v3.QueryTypeClickHouseSQL {
if strings.Contains(alert, "signoz_logs.distributed_logs") ||
strings.Contains(alert, "signoz_logs.logs") {
alertsInfo.AlertsWithLogsChQuery = alertsInfo.AlertsWithLogsChQuery + 1
}
}
}
for _, query := range rule.RuleCondition.CompositeQuery.BuilderQueries {
if rule.RuleCondition.CompositeQuery.QueryType == v3.QueryTypeBuilder {
if query.Filters != nil {
for _, item := range query.Filters.Items {
if slices.Contains([]string{"contains", "ncontains", "like", "nlike"}, string(item.Operator)) {
if item.Key.Key != "body" {
alertsInfo.AlertsWithLogsContainsOp += 1
}
}
}
}
}
}
} else if rule.AlertType == AlertTypeMetric {
alertsInfo.MetricBasedAlerts = alertsInfo.MetricBasedAlerts + 1
if rule.RuleCondition != nil && rule.RuleCondition.CompositeQuery != nil {

View File

@ -333,6 +333,7 @@ func createTelemetry() {
"dashboardNames": dashboardsInfo.DashboardNames,
"alertNames": alertsInfo.AlertNames,
"logsBasedPanels": dashboardsInfo.LogsBasedPanels,
"logsPanelsWithAttrContains": dashboardsInfo.LogsPanelsWithAttrContainsOp,
"metricBasedPanels": dashboardsInfo.MetricBasedPanels,
"tracesBasedPanels": dashboardsInfo.TracesBasedPanels,
"dashboardsWithTSV2": dashboardsInfo.QueriesWithTSV2,
@ -346,6 +347,7 @@ func createTelemetry() {
"totalSavedViews": savedViewsInfo.TotalSavedViews,
"logsSavedViews": savedViewsInfo.LogsSavedViews,
"tracesSavedViews": savedViewsInfo.TracesSavedViews,
"logSavedViewsWithContainsOp": savedViewsInfo.LogsSavedViewWithContainsOp,
"slackChannels": alertsInfo.SlackChannels,
"webHookChannels": alertsInfo.WebHookChannels,
"pagerDutyChannels": alertsInfo.PagerDutyChannels,
@ -357,6 +359,7 @@ func createTelemetry() {
"metricsPrometheusQueries": alertsInfo.MetricsPrometheusQueries,
"spanMetricsPrometheusQueries": alertsInfo.SpanMetricsPrometheusQueries,
"alertsWithLogsChQuery": alertsInfo.AlertsWithLogsChQuery,
"alertsWithLogsContainsOp": alertsInfo.AlertsWithLogsContainsOp,
}
// send event only if there are dashboards or alerts or channels
if (dashboardsInfo.TotalDashboards > 0 || alertsInfo.TotalAlerts > 0 || alertsInfo.TotalChannels > 0 || savedViewsInfo.TotalSavedViews > 0) && apiErr == nil {