From 4295a2756a5dacaad9dad4ff44f8e5f667a6e68e Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Thu, 29 Aug 2024 21:44:12 +0530 Subject: [PATCH 1/4] chore: remove old data migrations (#5802) --- .../migrate/0_45_alerts_to_v4/run.go | 153 ------------------ .../migrate/0_47_alerts_custom_step/run.go | 70 -------- pkg/query-service/migrate/migate.go | 25 --- 3 files changed, 248 deletions(-) delete mode 100644 pkg/query-service/migrate/0_45_alerts_to_v4/run.go delete mode 100644 pkg/query-service/migrate/0_47_alerts_custom_step/run.go diff --git a/pkg/query-service/migrate/0_45_alerts_to_v4/run.go b/pkg/query-service/migrate/0_45_alerts_to_v4/run.go deleted file mode 100644 index f68f4ca43b..0000000000 --- a/pkg/query-service/migrate/0_45_alerts_to_v4/run.go +++ /dev/null @@ -1,153 +0,0 @@ -package alertstov4 - -import ( - "context" - "encoding/json" - - "github.com/jmoiron/sqlx" - v3 "go.signoz.io/signoz/pkg/query-service/model/v3" - "go.signoz.io/signoz/pkg/query-service/rules" - "go.uber.org/multierr" - "go.uber.org/zap" -) - -var Version = "0.45-alerts-to-v4" - -var mapTimeAggregation = map[v3.AggregateOperator]v3.TimeAggregation{ - v3.AggregateOperatorSum: v3.TimeAggregationSum, - v3.AggregateOperatorMin: v3.TimeAggregationMin, - v3.AggregateOperatorMax: v3.TimeAggregationMax, - v3.AggregateOperatorSumRate: v3.TimeAggregationRate, - v3.AggregateOperatorAvgRate: v3.TimeAggregationRate, - v3.AggregateOperatorMinRate: v3.TimeAggregationRate, - v3.AggregateOperatorMaxRate: v3.TimeAggregationRate, - v3.AggregateOperatorHistQuant50: v3.TimeAggregationUnspecified, - v3.AggregateOperatorHistQuant75: v3.TimeAggregationUnspecified, - v3.AggregateOperatorHistQuant90: v3.TimeAggregationUnspecified, - v3.AggregateOperatorHistQuant95: v3.TimeAggregationUnspecified, - v3.AggregateOperatorHistQuant99: v3.TimeAggregationUnspecified, -} - -var mapSpaceAggregation = map[v3.AggregateOperator]v3.SpaceAggregation{ - v3.AggregateOperatorSum: v3.SpaceAggregationSum, - v3.AggregateOperatorMin: v3.SpaceAggregationMin, - v3.AggregateOperatorMax: v3.SpaceAggregationMax, - v3.AggregateOperatorSumRate: v3.SpaceAggregationSum, - v3.AggregateOperatorAvgRate: v3.SpaceAggregationAvg, - v3.AggregateOperatorMinRate: v3.SpaceAggregationMin, - v3.AggregateOperatorMaxRate: v3.SpaceAggregationMax, - v3.AggregateOperatorHistQuant50: v3.SpaceAggregationPercentile50, - v3.AggregateOperatorHistQuant75: v3.SpaceAggregationPercentile75, - v3.AggregateOperatorHistQuant90: v3.SpaceAggregationPercentile90, - v3.AggregateOperatorHistQuant95: v3.SpaceAggregationPercentile95, - v3.AggregateOperatorHistQuant99: v3.SpaceAggregationPercentile99, -} - -func canMigrateOperator(operator v3.AggregateOperator) bool { - switch operator { - case v3.AggregateOperatorSum, - v3.AggregateOperatorMin, - v3.AggregateOperatorMax, - v3.AggregateOperatorSumRate, - v3.AggregateOperatorAvgRate, - v3.AggregateOperatorMinRate, - v3.AggregateOperatorMaxRate, - v3.AggregateOperatorHistQuant50, - v3.AggregateOperatorHistQuant75, - v3.AggregateOperatorHistQuant90, - v3.AggregateOperatorHistQuant95, - v3.AggregateOperatorHistQuant99: - return true - } - return false -} - -func Migrate(conn *sqlx.DB) error { - ruleDB := rules.NewRuleDB(conn) - storedRules, err := ruleDB.GetStoredRules(context.Background()) - if err != nil { - return err - } - - for _, storedRule := range storedRules { - parsedRule, errs := rules.ParsePostableRule([]byte(storedRule.Data)) - if len(errs) > 0 { - // this should not happen but if it does, we should not stop the migration - zap.L().Error("Error parsing rule", zap.Error(multierr.Combine(errs...)), zap.Int("rule", storedRule.Id)) - continue - } - zap.L().Info("Rule parsed", zap.Int("rule", storedRule.Id)) - updated := false - if parsedRule.RuleCondition != nil && parsedRule.Version == "" { - if parsedRule.RuleCondition.QueryType() == v3.QueryTypeBuilder { - // check if all the queries can be converted to v4 - canMigrate := true - for _, query := range parsedRule.RuleCondition.CompositeQuery.BuilderQueries { - if query.DataSource == v3.DataSourceMetrics && query.Expression == query.QueryName { - if !canMigrateOperator(query.AggregateOperator) { - canMigrate = false - break - } - } - } - - if canMigrate { - parsedRule.Version = "v4" - for _, query := range parsedRule.RuleCondition.CompositeQuery.BuilderQueries { - if query.DataSource == v3.DataSourceMetrics && query.Expression == query.QueryName { - // update aggregate attribute - if query.AggregateOperator == v3.AggregateOperatorSum || - query.AggregateOperator == v3.AggregateOperatorMin || - query.AggregateOperator == v3.AggregateOperatorMax { - query.AggregateAttribute.Type = "Gauge" - } - if query.AggregateOperator == v3.AggregateOperatorSumRate || - query.AggregateOperator == v3.AggregateOperatorAvgRate || - query.AggregateOperator == v3.AggregateOperatorMinRate || - query.AggregateOperator == v3.AggregateOperatorMaxRate { - query.AggregateAttribute.Type = "Sum" - } - - if query.AggregateOperator == v3.AggregateOperatorHistQuant50 || - query.AggregateOperator == v3.AggregateOperatorHistQuant75 || - query.AggregateOperator == v3.AggregateOperatorHistQuant90 || - query.AggregateOperator == v3.AggregateOperatorHistQuant95 || - query.AggregateOperator == v3.AggregateOperatorHistQuant99 { - query.AggregateAttribute.Type = "Histogram" - } - query.AggregateAttribute.DataType = v3.AttributeKeyDataTypeFloat64 - query.AggregateAttribute.IsColumn = true - query.TimeAggregation = mapTimeAggregation[query.AggregateOperator] - query.SpaceAggregation = mapSpaceAggregation[query.AggregateOperator] - query.AggregateOperator = v3.AggregateOperator(query.TimeAggregation) - updated = true - } - } - } - } - } - - if !updated { - zap.L().Info("Rule not updated", zap.Int("rule", storedRule.Id)) - continue - } - - ruleJSON, jsonErr := json.Marshal(parsedRule) - if jsonErr != nil { - zap.L().Error("Error marshalling rule; skipping rule migration", zap.Error(jsonErr), zap.Int("rule", storedRule.Id)) - continue - } - - stmt, prepareError := conn.PrepareContext(context.Background(), `UPDATE rules SET data=$3 WHERE id=$4;`) - if prepareError != nil { - zap.L().Error("Error in preparing statement for UPDATE to rules", zap.Error(prepareError)) - continue - } - defer stmt.Close() - - if _, err := stmt.Exec(ruleJSON, storedRule.Id); err != nil { - zap.L().Error("Error in Executing prepared statement for UPDATE to rules", zap.Error(err)) - } - } - return nil -} diff --git a/pkg/query-service/migrate/0_47_alerts_custom_step/run.go b/pkg/query-service/migrate/0_47_alerts_custom_step/run.go deleted file mode 100644 index b25705aaf2..0000000000 --- a/pkg/query-service/migrate/0_47_alerts_custom_step/run.go +++ /dev/null @@ -1,70 +0,0 @@ -package alertscustomstep - -import ( - "context" - "encoding/json" - "time" - - "github.com/jmoiron/sqlx" - v3 "go.signoz.io/signoz/pkg/query-service/model/v3" - "go.signoz.io/signoz/pkg/query-service/rules" - "go.uber.org/multierr" - "go.uber.org/zap" -) - -var Version = "0.47-alerts-custom-step" - -func Migrate(conn *sqlx.DB) error { - ruleDB := rules.NewRuleDB(conn) - storedRules, err := ruleDB.GetStoredRules(context.Background()) - if err != nil { - return err - } - - for _, storedRule := range storedRules { - parsedRule, errs := rules.ParsePostableRule([]byte(storedRule.Data)) - if len(errs) > 0 { - // this should not happen but if it does, we should not stop the migration - zap.L().Error("Error parsing rule", zap.Error(multierr.Combine(errs...)), zap.Int("rule", storedRule.Id)) - continue - } - zap.L().Info("Rule parsed", zap.Int("rule", storedRule.Id)) - updated := false - if parsedRule.RuleCondition != nil { - if parsedRule.RuleCondition.QueryType() == v3.QueryTypeBuilder { - if parsedRule.EvalWindow <= rules.Duration(6*time.Hour) { - for _, query := range parsedRule.RuleCondition.CompositeQuery.BuilderQueries { - if query.StepInterval > 60 { - updated = true - zap.L().Info("Updating step interval", zap.Int("rule", storedRule.Id), zap.Int64("old", query.StepInterval), zap.Int64("new", 60)) - query.StepInterval = 60 - } - } - } - } - } - - if !updated { - zap.L().Info("Rule not updated", zap.Int("rule", storedRule.Id)) - continue - } - - ruleJSON, jsonErr := json.Marshal(parsedRule) - if jsonErr != nil { - zap.L().Error("Error marshalling rule; skipping rule migration", zap.Error(jsonErr), zap.Int("rule", storedRule.Id)) - continue - } - - stmt, prepareError := conn.PrepareContext(context.Background(), `UPDATE rules SET data=$3 WHERE id=$4;`) - if prepareError != nil { - zap.L().Error("Error in preparing statement for UPDATE to rules", zap.Error(prepareError)) - continue - } - defer stmt.Close() - - if _, err := stmt.Exec(ruleJSON, storedRule.Id); err != nil { - zap.L().Error("Error in Executing prepared statement for UPDATE to rules", zap.Error(err)) - } - } - return nil -} diff --git a/pkg/query-service/migrate/migate.go b/pkg/query-service/migrate/migate.go index bf5f3a7738..60e65d6d72 100644 --- a/pkg/query-service/migrate/migate.go +++ b/pkg/query-service/migrate/migate.go @@ -7,9 +7,6 @@ import ( "github.com/ClickHouse/clickhouse-go/v2/lib/driver" "github.com/jmoiron/sqlx" - alertstov4 "go.signoz.io/signoz/pkg/query-service/migrate/0_45_alerts_to_v4" - alertscustomstep "go.signoz.io/signoz/pkg/query-service/migrate/0_47_alerts_custom_step" - "go.uber.org/zap" ) type DataMigration struct { @@ -56,28 +53,6 @@ func Migrate(dsn string) error { return err } - if m, err := getMigrationVersion(conn, "0.45_alerts_to_v4"); err == nil && m == nil { - if err := alertstov4.Migrate(conn); err != nil { - zap.L().Error("failed to migrate 0.45_alerts_to_v4", zap.Error(err)) - } else { - _, err := conn.Exec("INSERT INTO data_migrations (version, succeeded) VALUES ('0.45_alerts_to_v4', true)") - if err != nil { - return err - } - } - } - - if m, err := getMigrationVersion(conn, "0.47_alerts_custom_step"); err == nil && m == nil { - if err := alertscustomstep.Migrate(conn); err != nil { - zap.L().Error("failed to migrate 0.47_alerts_custom_step", zap.Error(err)) - } else { - _, err := conn.Exec("INSERT INTO data_migrations (version, succeeded) VALUES ('0.47_alerts_custom_step', true)") - if err != nil { - return err - } - } - } - return nil } From 44598e304da35086ff91d76d3802fae5c650b22e Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Thu, 29 Aug 2024 21:53:28 +0530 Subject: [PATCH 2/4] chore: remove feature usage code from manager (#5803) --- pkg/query-service/rules/manager.go | 108 +---------------------------- 1 file changed, 1 insertion(+), 107 deletions(-) diff --git a/pkg/query-service/rules/manager.go b/pkg/query-service/rules/manager.go index 40764f9fb0..95f97753e0 100644 --- a/pkg/query-service/rules/manager.go +++ b/pkg/query-service/rules/manager.go @@ -20,11 +20,9 @@ import ( "github.com/jmoiron/sqlx" - // opentracing "github.com/opentracing/opentracing-go" am "go.signoz.io/signoz/pkg/query-service/integrations/alertManager" "go.signoz.io/signoz/pkg/query-service/interfaces" "go.signoz.io/signoz/pkg/query-service/model" - v3 "go.signoz.io/signoz/pkg/query-service/model/v3" "go.signoz.io/signoz/pkg/query-service/telemetry" "go.signoz.io/signoz/pkg/query-service/utils/labels" ) @@ -240,20 +238,6 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, id string) error parsedRule, errs := ParsePostableRule([]byte(ruleStr)) - currentRule, err := m.GetRule(ctx, id) - if err != nil { - zap.L().Error("failed to get the rule from rule db", zap.String("id", id), zap.Error(err)) - return err - } - - if !checkIfTraceOrLogQB(¤tRule.PostableRule) { - // check if the new rule uses any feature that is not enabled - err = m.checkFeatureUsage(parsedRule) - if err != nil { - return err - } - } - if len(errs) > 0 { zap.L().Error("failed to parse rules", zap.Errors("errors", errs)) // just one rule is being parsed so expect just one error @@ -272,20 +256,6 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, id string) error } } - // update feature usage if the current rule is not a trace or log query builder - if !checkIfTraceOrLogQB(¤tRule.PostableRule) { - err = m.updateFeatureUsage(parsedRule, 1) - if err != nil { - zap.L().Error("error updating feature usage", zap.Error(err)) - } - // update feature usage if the new rule is not a trace or log query builder and the current rule is - } else if !checkIfTraceOrLogQB(parsedRule) { - err = m.updateFeatureUsage(¤tRule.PostableRule, -1) - if err != nil { - zap.L().Error("error updating feature usage", zap.Error(err)) - } - } - return nil } @@ -335,13 +305,6 @@ func (m *Manager) DeleteRule(ctx context.Context, id string) error { return fmt.Errorf("delete rule received an rule id in invalid format, must be a number") } - // update feature usage - rule, err := m.GetRule(ctx, id) - if err != nil { - zap.L().Error("failed to get the rule from rule db", zap.String("id", id), zap.Error(err)) - return err - } - taskName := prepareTaskName(int64(idInt)) if !m.opts.DisableRules { m.deleteTask(taskName) @@ -352,11 +315,6 @@ func (m *Manager) DeleteRule(ctx context.Context, id string) error { return err } - err = m.updateFeatureUsage(&rule.PostableRule, -1) - if err != nil { - zap.L().Error("error updating feature usage", zap.Error(err)) - } - return nil } @@ -381,12 +339,6 @@ func (m *Manager) deleteTask(taskName string) { func (m *Manager) CreateRule(ctx context.Context, ruleStr string) (*GettableRule, error) { parsedRule, errs := ParsePostableRule([]byte(ruleStr)) - // check if the rule uses any feature that is not enabled - err := m.checkFeatureUsage(parsedRule) - if err != nil { - return nil, err - } - if len(errs) > 0 { zap.L().Error("failed to parse rules", zap.Errors("errors", errs)) // just one rule is being parsed so expect just one error @@ -409,11 +361,6 @@ func (m *Manager) CreateRule(ctx context.Context, ruleStr string) (*GettableRule return nil, err } - // update feature usage - err = m.updateFeatureUsage(parsedRule, 1) - if err != nil { - zap.L().Error("error updating feature usage", zap.Error(err)) - } gettableRule := &GettableRule{ Id: fmt.Sprintf("%d", lastInsertId), PostableRule: *parsedRule, @@ -421,59 +368,6 @@ func (m *Manager) CreateRule(ctx context.Context, ruleStr string) (*GettableRule return gettableRule, nil } -func (m *Manager) updateFeatureUsage(parsedRule *PostableRule, usage int64) error { - isTraceOrLogQB := checkIfTraceOrLogQB(parsedRule) - if isTraceOrLogQB { - feature, err := m.featureFlags.GetFeatureFlag(model.QueryBuilderAlerts) - if err != nil { - return err - } - feature.Usage += usage - if feature.Usage == feature.UsageLimit && feature.UsageLimit != -1 { - feature.Active = false - } - if feature.Usage < feature.UsageLimit || feature.UsageLimit == -1 { - feature.Active = true - } - err = m.featureFlags.UpdateFeatureFlag(feature) - if err != nil { - return err - } - } - return nil -} - -func (m *Manager) checkFeatureUsage(parsedRule *PostableRule) error { - isTraceOrLogQB := checkIfTraceOrLogQB(parsedRule) - if isTraceOrLogQB { - err := m.featureFlags.CheckFeature(model.QueryBuilderAlerts) - if err != nil { - switch err.(type) { - case model.ErrFeatureUnavailable: - zap.L().Error("feature unavailable", zap.String("featureKey", model.QueryBuilderAlerts), zap.Error(err)) - return model.BadRequest(err) - default: - zap.L().Error("feature check failed", zap.String("featureKey", model.QueryBuilderAlerts), zap.Error(err)) - return model.BadRequest(err) - } - } - } - return nil -} - -func checkIfTraceOrLogQB(parsedRule *PostableRule) bool { - if parsedRule != nil { - if parsedRule.RuleCondition.QueryType() == v3.QueryTypeBuilder { - for _, query := range parsedRule.RuleCondition.CompositeQuery.BuilderQueries { - if query.DataSource == v3.DataSourceTraces || query.DataSource == v3.DataSourceLogs { - return true - } - } - } - } - return false -} - func (m *Manager) addTask(rule *PostableRule, taskName string) error { m.mtx.Lock() defer m.mtx.Unlock() @@ -569,7 +463,7 @@ func (m *Manager) prepareTask(acquireLock bool, r *PostableRule, taskName string m.rules[ruleId] = pr } else { - return nil, fmt.Errorf(fmt.Sprintf("unsupported rule type. Supported types: %s, %s", RuleTypeProm, RuleTypeThreshold)) + return nil, fmt.Errorf("unsupported rule type. Supported types: %s, %s", RuleTypeProm, RuleTypeThreshold) } return task, nil From dde4485839bc7a3c1f8e9b13d7fb99ae0b097bb0 Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Fri, 30 Aug 2024 10:34:11 +0530 Subject: [PATCH 3/4] chore: add types for alert type, state, and rule data kind (#5804) --- pkg/query-service/app/http_handler.go | 10 +++--- pkg/query-service/rules/alerting.go | 29 +++++++++++++++++ pkg/query-service/rules/api_params.go | 32 ++++++++++++++----- pkg/query-service/rules/db.go | 6 ++-- pkg/query-service/rules/manager.go | 12 +++---- pkg/query-service/rules/threshold_rule.go | 7 ++-- .../rules/threshold_rule_test.go | 2 +- 7 files changed, 71 insertions(+), 27 deletions(-) diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 5d3d9affd5..1210cd4f67 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -805,7 +805,7 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request continue } filterItems := []v3.FilterItem{} - if rule.AlertType == "LOGS_BASED_ALERT" || rule.AlertType == "TRACES_BASED_ALERT" { + if rule.AlertType == rules.AlertTypeLogs || rule.AlertType == rules.AlertTypeTraces { if rule.RuleCondition.CompositeQuery != nil { if rule.RuleCondition.QueryType() == v3.QueryTypeBuilder { for _, query := range rule.RuleCondition.CompositeQuery.BuilderQueries { @@ -818,9 +818,9 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request } newFilters := common.PrepareFilters(lbls, filterItems) ts := time.Unix(res.Items[idx].UnixMilli/1000, 0) - if rule.AlertType == "LOGS_BASED_ALERT" { + if rule.AlertType == rules.AlertTypeLogs { res.Items[idx].RelatedLogsLink = common.PrepareLinksToLogs(ts, newFilters) - } else if rule.AlertType == "TRACES_BASED_ALERT" { + } else if rule.AlertType == rules.AlertTypeTraces { res.Items[idx].RelatedTracesLink = common.PrepareLinksToTraces(ts, newFilters) } } @@ -854,9 +854,9 @@ func (aH *APIHandler) getRuleStateHistoryTopContributors(w http.ResponseWriter, } ts := time.Unix(params.End/1000, 0) filters := common.PrepareFilters(lbls, nil) - if rule.AlertType == "LOGS_BASED_ALERT" { + if rule.AlertType == rules.AlertTypeLogs { res[idx].RelatedLogsLink = common.PrepareLinksToLogs(ts, filters) - } else if rule.AlertType == "TRACES_BASED_ALERT" { + } else if rule.AlertType == rules.AlertTypeTraces { res[idx].RelatedTracesLink = common.PrepareLinksToTraces(ts, filters) } } diff --git a/pkg/query-service/rules/alerting.go b/pkg/query-service/rules/alerting.go index 36a0ea1b69..7c7fb40ed6 100644 --- a/pkg/query-service/rules/alerting.go +++ b/pkg/query-service/rules/alerting.go @@ -61,6 +61,35 @@ func (s AlertState) String() string { panic(errors.Errorf("unknown alert state: %d", s)) } +func (s AlertState) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +func (s *AlertState) UnmarshalJSON(b []byte) error { + var v interface{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + switch value := v.(type) { + case string: + switch value { + case "inactive": + *s = StateInactive + case "pending": + *s = StatePending + case "firing": + *s = StateFiring + case "disabled": + *s = StateDisabled + default: + return errors.New("invalid alert state") + } + return nil + default: + return errors.New("invalid alert state") + } +} + type Alert struct { State AlertState diff --git a/pkg/query-service/rules/api_params.go b/pkg/query-service/rules/api_params.go index 74ca041aae..890d464671 100644 --- a/pkg/query-service/rules/api_params.go +++ b/pkg/query-service/rules/api_params.go @@ -16,6 +16,22 @@ import ( yaml "gopkg.in/yaml.v2" ) +type AlertType string + +const ( + AlertTypeMetric AlertType = "METRIC_BASED_ALERT" + AlertTypeTraces AlertType = "TRACES_BASED_ALERT" + AlertTypeLogs AlertType = "LOGS_BASED_ALERT" + AlertTypeExceptions AlertType = "EXCEPTIONS_BASED_ALERT" +) + +type RuleDataKind string + +const ( + RuleDataKindJson RuleDataKind = "json" + RuleDataKindYaml RuleDataKind = "yaml" +) + // this file contains api request and responses to be // served over http @@ -31,12 +47,12 @@ func newApiErrorBadData(err error) *model.ApiError { // PostableRule is used to create alerting rule from HTTP api type PostableRule struct { - AlertName string `yaml:"alert,omitempty" json:"alert,omitempty"` - AlertType string `yaml:"alertType,omitempty" json:"alertType,omitempty"` - Description string `yaml:"description,omitempty" json:"description,omitempty"` - RuleType RuleType `yaml:"ruleType,omitempty" json:"ruleType,omitempty"` - EvalWindow Duration `yaml:"evalWindow,omitempty" json:"evalWindow,omitempty"` - Frequency Duration `yaml:"frequency,omitempty" json:"frequency,omitempty"` + AlertName string `yaml:"alert,omitempty" json:"alert,omitempty"` + AlertType AlertType `yaml:"alertType,omitempty" json:"alertType,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + RuleType RuleType `yaml:"ruleType,omitempty" json:"ruleType,omitempty"` + EvalWindow Duration `yaml:"evalWindow,omitempty" json:"evalWindow,omitempty"` + Frequency Duration `yaml:"frequency,omitempty" json:"frequency,omitempty"` RuleCondition *RuleCondition `yaml:"condition,omitempty" json:"condition,omitempty"` Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"` @@ -234,8 +250,8 @@ type GettableRules struct { // GettableRule has info for an alerting rules. type GettableRule struct { - Id string `json:"id"` - State string `json:"state"` + Id string `json:"id"` + State AlertState `json:"state"` PostableRule CreatedAt *time.Time `json:"createAt"` CreatedBy *string `json:"createBy"` diff --git a/pkg/query-service/rules/db.go b/pkg/query-service/rules/db.go index 37e45f2711..d9a9be195c 100644 --- a/pkg/query-service/rules/db.go +++ b/pkg/query-service/rules/db.go @@ -325,9 +325,9 @@ func (r *ruleDB) GetAlertsInfo(ctx context.Context) (*model.AlertsInfo, error) { continue } alertNames = append(alertNames, rule.AlertName) - if rule.AlertType == "LOGS_BASED_ALERT" { + if rule.AlertType == AlertTypeLogs { alertsInfo.LogsBasedAlerts = alertsInfo.LogsBasedAlerts + 1 - } else if rule.AlertType == "METRIC_BASED_ALERT" { + } else if rule.AlertType == AlertTypeMetric { alertsInfo.MetricBasedAlerts = alertsInfo.MetricBasedAlerts + 1 if rule.RuleCondition != nil && rule.RuleCondition.CompositeQuery != nil { if rule.RuleCondition.CompositeQuery.QueryType == v3.QueryTypeBuilder { @@ -343,7 +343,7 @@ func (r *ruleDB) GetAlertsInfo(ctx context.Context) (*model.AlertsInfo, error) { } } } - } else if rule.AlertType == "TRACES_BASED_ALERT" { + } else if rule.AlertType == AlertTypeTraces { alertsInfo.TracesBasedAlerts = alertsInfo.TracesBasedAlerts + 1 } alertsInfo.TotalAlerts = alertsInfo.TotalAlerts + 1 diff --git a/pkg/query-service/rules/manager.go b/pkg/query-service/rules/manager.go index 95f97753e0..f738fefcc7 100644 --- a/pkg/query-service/rules/manager.go +++ b/pkg/query-service/rules/manager.go @@ -604,10 +604,10 @@ func (m *Manager) ListRuleStates(ctx context.Context) (*GettableRules, error) { // fetch state of rule from memory if rm, ok := m.rules[ruleResponse.Id]; !ok { - ruleResponse.State = StateDisabled.String() + ruleResponse.State = StateDisabled ruleResponse.Disabled = true } else { - ruleResponse.State = rm.State().String() + ruleResponse.State = rm.State() } ruleResponse.CreatedAt = s.CreatedAt ruleResponse.CreatedBy = s.CreatedBy @@ -631,10 +631,10 @@ func (m *Manager) GetRule(ctx context.Context, id string) (*GettableRule, error) r.Id = fmt.Sprintf("%d", s.Id) // fetch state of rule from memory if rm, ok := m.rules[r.Id]; !ok { - r.State = StateDisabled.String() + r.State = StateDisabled r.Disabled = true } else { - r.State = rm.State().String() + r.State = rm.State() } r.CreatedAt = s.CreatedAt r.CreatedBy = s.CreatedBy @@ -740,10 +740,10 @@ func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleId string) // fetch state of rule from memory if rm, ok := m.rules[ruleId]; !ok { - response.State = StateDisabled.String() + response.State = StateDisabled response.Disabled = true } else { - response.State = rm.State().String() + response.State = rm.State() } return &response, nil diff --git a/pkg/query-service/rules/threshold_rule.go b/pkg/query-service/rules/threshold_rule.go index 5093e407dc..9bdecbc63d 100644 --- a/pkg/query-service/rules/threshold_rule.go +++ b/pkg/query-service/rules/threshold_rule.go @@ -91,8 +91,7 @@ type ThresholdRule struct { lastTimestampWithDatapoints time.Time // Type of the rule - // One of ["LOGS_BASED_ALERT", "TRACES_BASED_ALERT", "METRIC_BASED_ALERT", "EXCEPTIONS_BASED_ALERT"] - typ string + typ AlertType // querier is used for alerts created before the introduction of new metrics query builder querier interfaces.Querier @@ -975,12 +974,12 @@ func (r *ThresholdRule) Eval(ctx context.Context, ts time.Time, queriers *Querie // Links with timestamps should go in annotations since labels // is used alert grouping, and we want to group alerts with the same // label set, but different timestamps, together. - if r.typ == "TRACES_BASED_ALERT" { + if r.typ == AlertTypeTraces { link := r.prepareLinksToTraces(ts, smpl.MetricOrig) if link != "" && r.hostFromSource() != "" { annotations = append(annotations, labels.Label{Name: "related_traces", Value: fmt.Sprintf("%s/traces-explorer?%s", r.hostFromSource(), link)}) } - } else if r.typ == "LOGS_BASED_ALERT" { + } else if r.typ == AlertTypeLogs { link := r.prepareLinksToLogs(ts, smpl.MetricOrig) if link != "" && r.hostFromSource() != "" { annotations = append(annotations, labels.Label{Name: "related_logs", Value: fmt.Sprintf("%s/logs/logs-explorer?%s", r.hostFromSource(), link)}) diff --git a/pkg/query-service/rules/threshold_rule_test.go b/pkg/query-service/rules/threshold_rule_test.go index 55a831efcd..05bd613900 100644 --- a/pkg/query-service/rules/threshold_rule_test.go +++ b/pkg/query-service/rules/threshold_rule_test.go @@ -674,7 +674,7 @@ func TestNormalizeLabelName(t *testing.T) { func TestPrepareLinksToLogs(t *testing.T) { postableRule := PostableRule{ AlertName: "Tricky Condition Tests", - AlertType: "LOGS_BASED_ALERT", + AlertType: AlertTypeLogs, RuleType: RuleTypeThreshold, EvalWindow: Duration(5 * time.Minute), Frequency: Duration(1 * time.Minute), From 363fb7bc34bce1cfb10a27451c329312142b86a7 Mon Sep 17 00:00:00 2001 From: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com> Date: Fri, 30 Aug 2024 12:00:52 +0530 Subject: [PATCH 4/4] feat: Kafka UI feedbacks (#5801) * fix: solved kafka feature feedbacks * fix: changed coming soon text to - join slack community --- .../SideNav/NavItem/NavItem.styles.scss | 4 ++ .../src/container/SideNav/NavItem/NavItem.tsx | 2 +- frontend/src/container/SideNav/menuItems.tsx | 1 + .../MessagingQueues/MQCommon/MQCommon.tsx | 14 ++++++- .../MQDetailPage/MQDetailPage.tsx | 38 ++++++++++++------- .../MessagingQueues.styles.scss | 2 +- .../pages/MessagingQueues/MessagingQueues.tsx | 13 ++++--- .../MessagingQueues/MessagingQueuesUtils.ts | 19 ++++++++++ 8 files changed, 72 insertions(+), 21 deletions(-) diff --git a/frontend/src/container/SideNav/NavItem/NavItem.styles.scss b/frontend/src/container/SideNav/NavItem/NavItem.styles.scss index aea7b3a0ee..ede4376033 100644 --- a/frontend/src/container/SideNav/NavItem/NavItem.styles.scss +++ b/frontend/src/container/SideNav/NavItem/NavItem.styles.scss @@ -75,6 +75,10 @@ text-overflow: ellipsis; } } + + .beta-tag { + padding-right: 0; + } } .lightMode { diff --git a/frontend/src/container/SideNav/NavItem/NavItem.tsx b/frontend/src/container/SideNav/NavItem/NavItem.tsx index b3d57193f1..97a8cdb0ed 100644 --- a/frontend/src/container/SideNav/NavItem/NavItem.tsx +++ b/frontend/src/container/SideNav/NavItem/NavItem.tsx @@ -24,7 +24,7 @@ export default function NavItem({ onClick={(event): void => onClick(event)} >
-
+
{icon}
{label}
diff --git a/frontend/src/container/SideNav/menuItems.tsx b/frontend/src/container/SideNav/menuItems.tsx index 1566141735..be694227a1 100644 --- a/frontend/src/container/SideNav/menuItems.tsx +++ b/frontend/src/container/SideNav/menuItems.tsx @@ -91,6 +91,7 @@ const menuItems: SidebarItem[] = [ key: ROUTES.MESSAGING_QUEUES, label: 'Messaging Queues', icon: , + isBeta: true, }, { key: ROUTES.LIST_ALL_ALERT, diff --git a/frontend/src/pages/MessagingQueues/MQCommon/MQCommon.tsx b/frontend/src/pages/MessagingQueues/MQCommon/MQCommon.tsx index 1d5394a14a..ce6fd1e96f 100644 --- a/frontend/src/pages/MessagingQueues/MQCommon/MQCommon.tsx +++ b/frontend/src/pages/MessagingQueues/MQCommon/MQCommon.tsx @@ -9,7 +9,19 @@ import { Info } from 'lucide-react'; export function ComingSoon(): JSX.Element { return ( + Join our Slack community for more details:{' '} + e.stopPropagation()} + > + SigNoz Community + +
+ } placement="top" overlayClassName="tooltip-overlay" > diff --git a/frontend/src/pages/MessagingQueues/MQDetailPage/MQDetailPage.tsx b/frontend/src/pages/MessagingQueues/MQDetailPage/MQDetailPage.tsx index 17baff2790..f82a2f605d 100644 --- a/frontend/src/pages/MessagingQueues/MQDetailPage/MQDetailPage.tsx +++ b/frontend/src/pages/MessagingQueues/MQDetailPage/MQDetailPage.tsx @@ -6,17 +6,12 @@ import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; import { ListMinus } from 'lucide-react'; import { useHistory } from 'react-router-dom'; +import { MessagingQueuesViewType } from '../MessagingQueuesUtils'; import { SelectLabelWithComingSoon } from '../MQCommon/MQCommon'; import MessagingQueuesDetails from '../MQDetails/MQDetails'; import MessagingQueuesConfigOptions from '../MQGraph/MQConfigOptions'; import MessagingQueuesGraph from '../MQGraph/MQGraph'; -enum MessagingQueueViewType { - consumerLag = 'consumerLag', - avgPartitionLatency = 'avgPartitionLatency', - avgProducerLatency = 'avgProducerLatency', -} - function MQDetailPage(): JSX.Element { const history = useHistory(); @@ -36,21 +31,38 @@ function MQDetailPage(): JSX.Element { Kafka / views /