diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index cff6c4731b2c..15eb4d41fa70 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -64,6 +64,7 @@ import ( "github.com/SigNoz/signoz/pkg/types/licensetypes" "github.com/SigNoz/signoz/pkg/types/opamptypes" "github.com/SigNoz/signoz/pkg/types/pipelinetypes" + qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes" traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes" @@ -1035,9 +1036,54 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request // to get the correct query range start := end.Add(-time.Duration(rule.EvalWindow)).Add(-3 * time.Minute) if rule.AlertType == ruletypes.AlertTypeLogs { - res.Items[idx].RelatedLogsLink = contextlinks.PrepareLinksToLogs(start, end, newFilters) + if rule.Version != "v5" { + res.Items[idx].RelatedLogsLink = contextlinks.PrepareLinksToLogs(start, end, newFilters) + } else { + // TODO(srikanthccv): re-visit this and support multiple queries + var q qbtypes.QueryBuilderQuery[qbtypes.LogAggregation] + + for _, query := range rule.RuleCondition.CompositeQuery.Queries { + if query.Type == qbtypes.QueryTypeBuilder { + switch spec := query.Spec.(type) { + case qbtypes.QueryBuilderQuery[qbtypes.LogAggregation]: + q = spec + } + } + } + + filterExpr := "" + if q.Filter != nil && q.Filter.Expression != "" { + filterExpr = q.Filter.Expression + } + + whereClause := contextlinks.PrepareFilterExpression(lbls, filterExpr, q.GroupBy) + + res.Items[idx].RelatedLogsLink = contextlinks.PrepareLinksToLogsV5(start, end, whereClause) + } } else if rule.AlertType == ruletypes.AlertTypeTraces { - res.Items[idx].RelatedTracesLink = contextlinks.PrepareLinksToTraces(start, end, newFilters) + if rule.Version != "v5" { + res.Items[idx].RelatedTracesLink = contextlinks.PrepareLinksToTraces(start, end, newFilters) + } else { + // TODO(srikanthccv): re-visit this and support multiple queries + var q qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation] + + for _, query := range rule.RuleCondition.CompositeQuery.Queries { + if query.Type == qbtypes.QueryTypeBuilder { + switch spec := query.Spec.(type) { + case qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation]: + q = spec + } + } + } + + filterExpr := "" + if q.Filter != nil && q.Filter.Expression != "" { + filterExpr = q.Filter.Expression + } + + whereClause := contextlinks.PrepareFilterExpression(lbls, filterExpr, q.GroupBy) + res.Items[idx].RelatedTracesLink = contextlinks.PrepareLinksToTracesV5(start, end, whereClause) + } } } } diff --git a/pkg/query-service/rules/threshold_rule.go b/pkg/query-service/rules/threshold_rule.go index 4287da15f913..6828d3221105 100644 --- a/pkg/query-service/rules/threshold_rule.go +++ b/pkg/query-service/rules/threshold_rule.go @@ -478,6 +478,11 @@ func (r *ThresholdRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID, return resultVector, nil } + if queryResult == nil { + r.logger.WarnContext(ctx, "query result is nil", "rule_name", r.Name(), "query_name", selectedQuery) + return resultVector, nil + } + for _, series := range queryResult.Series { smpl, shouldAlert := r.ShouldAlert(*series) if shouldAlert { diff --git a/pkg/transition/migrate_alert.go b/pkg/transition/migrate_alert.go index b655ccdcd7b0..9a7b9603b71c 100644 --- a/pkg/transition/migrate_alert.go +++ b/pkg/transition/migrate_alert.go @@ -73,7 +73,7 @@ func (m *alertMigrateV5) Migrate(ctx context.Context, ruleData map[string]any) b panelType = pt } - if m.updateQueryData(ctx, queryMap, "v4", panelType) { + if m.updateQueryData(ctx, queryMap, version, panelType) { updated = true } m.logger.InfoContext(ctx, "migrated querymap") diff --git a/pkg/types/ruletypes/alerting.go b/pkg/types/ruletypes/alerting.go index f76d5a3ec79d..32f276163651 100644 --- a/pkg/types/ruletypes/alerting.go +++ b/pkg/types/ruletypes/alerting.go @@ -11,6 +11,8 @@ import ( "github.com/SigNoz/signoz/pkg/query-service/model" v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3" "github.com/SigNoz/signoz/pkg/query-service/utils/labels" + + qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" ) // this file contains common structs and methods used by @@ -131,10 +133,30 @@ func (rc *RuleCondition) GetSelectedQueryName() string { for name := range rc.CompositeQuery.BuilderQueries { queryNames[name] = struct{}{} } + + for _, query := range rc.CompositeQuery.Queries { + switch spec := query.Spec.(type) { + case qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation]: + queryNames[spec.Name] = struct{}{} + case qbtypes.QueryBuilderQuery[qbtypes.LogAggregation]: + queryNames[spec.Name] = struct{}{} + case qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]: + queryNames[spec.Name] = struct{}{} + case qbtypes.QueryBuilderFormula: + queryNames[spec.Name] = struct{}{} + } + } } else if rc.QueryType() == v3.QueryTypeClickHouseSQL { for name := range rc.CompositeQuery.ClickHouseQueries { queryNames[name] = struct{}{} } + + for _, query := range rc.CompositeQuery.Queries { + switch spec := query.Spec.(type) { + case qbtypes.ClickHouseQuery: + queryNames[spec.Name] = struct{}{} + } + } } }