mirror of
https://github.com/SigNoz/signoz.git
synced 2026-02-09 11:12:21 +00:00
Compare commits
4 Commits
test/toolt
...
chore/avoi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
662bfa5b7b | ||
|
|
ecbf8b21be | ||
|
|
a31038d23c | ||
|
|
444beeca34 |
@@ -249,7 +249,7 @@ func (r *AnomalyRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID, t
|
||||
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
|
||||
continue
|
||||
}
|
||||
results, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
|
||||
results, err := r.Threshold.Eval(series, r.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: r.ActiveAlertsLabelFP(),
|
||||
SendUnmatched: r.ShouldSendUnmatched(),
|
||||
})
|
||||
@@ -317,7 +317,7 @@ func (r *AnomalyRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUID,
|
||||
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
|
||||
continue
|
||||
}
|
||||
results, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
|
||||
results, err := r.Threshold.Eval(series, r.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: r.ActiveAlertsLabelFP(),
|
||||
SendUnmatched: r.ShouldSendUnmatched(),
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
@@ -169,7 +170,7 @@ func (r *PromRule) buildAndRunQuery(ctx context.Context, ts time.Time) (ruletype
|
||||
)
|
||||
continue
|
||||
}
|
||||
resultSeries, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
|
||||
resultSeries, err := r.Threshold.Eval(series, r.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: r.ActiveAlertsLabelFP(),
|
||||
SendUnmatched: r.ShouldSendUnmatched(),
|
||||
})
|
||||
@@ -467,6 +468,10 @@ func toCommonSeries(series promql.Series) v3.Series {
|
||||
}
|
||||
|
||||
for _, f := range series.Floats {
|
||||
// skip the point if it is nan, inf, or timestamp is zero
|
||||
if math.IsNaN(f.F) || math.IsInf(f.F, 0) || f.T == 0 {
|
||||
continue
|
||||
}
|
||||
commonSeries.Points = append(commonSeries.Points, v3.Point{
|
||||
Timestamp: f.T,
|
||||
Value: f.F,
|
||||
|
||||
@@ -708,7 +708,8 @@ func TestPromRuleEval(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
resultVectors, err := rule.Threshold.Eval(toCommonSeries(c.values), rule.Unit(), ruletypes.EvalData{})
|
||||
series := toCommonSeries(c.values)
|
||||
resultVectors, err := rule.Threshold.Eval(&series, rule.Unit(), ruletypes.EvalData{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Compare full result vector with expected vector
|
||||
|
||||
@@ -478,7 +478,7 @@ func (r *ThresholdRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID,
|
||||
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
|
||||
continue
|
||||
}
|
||||
resultSeries, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
|
||||
resultSeries, err := r.Threshold.Eval(series, r.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: r.ActiveAlertsLabelFP(),
|
||||
SendUnmatched: r.ShouldSendUnmatched(),
|
||||
})
|
||||
@@ -553,7 +553,7 @@ func (r *ThresholdRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUI
|
||||
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
|
||||
continue
|
||||
}
|
||||
resultSeries, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
|
||||
resultSeries, err := r.Threshold.Eval(series, r.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: r.ActiveAlertsLabelFP(),
|
||||
SendUnmatched: r.ShouldSendUnmatched(),
|
||||
})
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestThresholdRuleEvalBackwardCompat(t *testing.T) {
|
||||
values.Points[i].Timestamp = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
resultVectors, err := rule.Threshold.Eval(c.values, rule.Unit(), ruletypes.EvalData{
|
||||
resultVectors, err := rule.Threshold.Eval(&c.values, rule.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: map[uint64]struct{}{},
|
||||
})
|
||||
assert.NoError(t, err, "Test case %d", idx)
|
||||
@@ -461,7 +461,7 @@ func TestThresholdRuleLabelNormalization(t *testing.T) {
|
||||
values.Points[i].Timestamp = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
vector, err := rule.Threshold.Eval(c.values, rule.Unit(), ruletypes.EvalData{})
|
||||
vector, err := rule.Threshold.Eval(&c.values, rule.Unit(), ruletypes.EvalData{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
for name, value := range c.values.Labels {
|
||||
@@ -471,7 +471,7 @@ func TestThresholdRuleLabelNormalization(t *testing.T) {
|
||||
}
|
||||
|
||||
// Get result vectors from threshold evaluation
|
||||
resultVectors, err := rule.Threshold.Eval(c.values, rule.Unit(), ruletypes.EvalData{})
|
||||
resultVectors, err := rule.Threshold.Eval(&c.values, rule.Unit(), ruletypes.EvalData{})
|
||||
assert.NoError(t, err, "Test case %d", idx)
|
||||
|
||||
// Compare result vectors with expected behavior
|
||||
@@ -1582,7 +1582,7 @@ func TestThresholdRuleEval_SendUnmatchedBypassesRecovery(t *testing.T) {
|
||||
alertLabels := ruletypes.PrepareSampleLabelsForRule(series.Labels, "primary")
|
||||
activeAlerts := map[uint64]struct{}{alertLabels.Hash(): {}}
|
||||
|
||||
resultVectors, err := rule.Threshold.Eval(series, rule.Unit(), ruletypes.EvalData{
|
||||
resultVectors, err := rule.Threshold.Eval(&series, rule.Unit(), ruletypes.EvalData{
|
||||
ActiveAlerts: activeAlerts,
|
||||
SendUnmatched: true,
|
||||
})
|
||||
@@ -1850,7 +1850,7 @@ func runEvalTests(t *testing.T, postableRule ruletypes.PostableRule, testCases [
|
||||
SendUnmatched: c.sendUnmatched,
|
||||
}
|
||||
|
||||
resultVectors, err := rule.Threshold.Eval(values, rule.Unit(), evalData)
|
||||
resultVectors, err := rule.Threshold.Eval(&values, rule.Unit(), evalData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if c.expectSamples != nil {
|
||||
@@ -1958,7 +1958,7 @@ func runMultiThresholdEvalTests(t *testing.T, postableRule ruletypes.PostableRul
|
||||
ActiveAlerts: activeAlerts,
|
||||
}
|
||||
|
||||
resultVectors, err := rule.Threshold.Eval(values, rule.Unit(), evalData)
|
||||
resultVectors, err := rule.Threshold.Eval(&values, rule.Unit(), evalData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Validate total sample count
|
||||
|
||||
@@ -2,6 +2,7 @@ package transition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
@@ -39,6 +40,11 @@ func ConvertV5TimeSeriesDataToV4Result(v5Data *qbtypes.TimeSeriesData) *v3.Resul
|
||||
continue
|
||||
}
|
||||
|
||||
// skip the point if it is nan, inf, or timestamp is zero
|
||||
if math.IsNaN(tsValue.Value) || math.IsInf(tsValue.Value, 0) || tsValue.Timestamp == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
point := v3.Point{
|
||||
Timestamp: tsValue.Timestamp,
|
||||
Value: tsValue.Value,
|
||||
|
||||
@@ -621,7 +621,7 @@ func TestParseIntoRuleThresholdGeneration(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test that threshold can evaluate properly
|
||||
vector, err := threshold.Eval(v3.Series{
|
||||
vector, err := threshold.Eval(&v3.Series{
|
||||
Points: []v3.Point{{Value: 0.15, Timestamp: 1000}}, // 150ms in seconds
|
||||
Labels: map[string]string{"test": "label"},
|
||||
}, "", EvalData{})
|
||||
@@ -698,7 +698,7 @@ func TestParseIntoRuleMultipleThresholds(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test with a value that should trigger both WARNING and CRITICAL thresholds
|
||||
vector, err := threshold.Eval(v3.Series{
|
||||
vector, err := threshold.Eval(&v3.Series{
|
||||
Points: []v3.Point{{Value: 95.0, Timestamp: 1000}}, // 95% CPU usage
|
||||
Labels: map[string]string{"service": "test"},
|
||||
}, "", EvalData{})
|
||||
@@ -708,7 +708,7 @@ func TestParseIntoRuleMultipleThresholds(t *testing.T) {
|
||||
|
||||
assert.Equal(t, 2, len(vector))
|
||||
|
||||
vector, err = threshold.Eval(v3.Series{
|
||||
vector, err = threshold.Eval(&v3.Series{
|
||||
Points: []v3.Point{{Value: 75.0, Timestamp: 1000}}, // 75% CPU usage
|
||||
Labels: map[string]string{"service": "test"},
|
||||
}, "", EvalData{})
|
||||
@@ -1046,7 +1046,7 @@ func TestAnomalyNegationEval(t *testing.T) {
|
||||
t.Fatalf("unexpected error from GetRuleThreshold: %v", err)
|
||||
}
|
||||
|
||||
resultVector, err := ruleThreshold.Eval(tt.series, "", EvalData{})
|
||||
resultVector, err := ruleThreshold.Eval(&tt.series, "", EvalData{})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error from Eval: %v", err)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (eval EvalData) HasActiveAlert(sampleLabelFp uint64) bool {
|
||||
type RuleThreshold interface {
|
||||
// Eval runs the given series through the threshold rules
|
||||
// using the given EvalData and returns the matching series
|
||||
Eval(series v3.Series, unit string, evalData EvalData) (Vector, error)
|
||||
Eval(series *v3.Series, unit string, evalData EvalData) (Vector, error)
|
||||
GetRuleReceivers() []RuleReceivers
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func (r BasicRuleThresholds) Validate() error {
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (r BasicRuleThresholds) Eval(series v3.Series, unit string, evalData EvalData) (Vector, error) {
|
||||
func (r BasicRuleThresholds) Eval(series *v3.Series, unit string, evalData EvalData) (Vector, error) {
|
||||
var resultVector Vector
|
||||
thresholds := []BasicRuleThreshold(r)
|
||||
sortThresholds(thresholds)
|
||||
@@ -137,8 +137,6 @@ func (r BasicRuleThresholds) Eval(series v3.Series, unit string, evalData EvalDa
|
||||
resultVector = append(resultVector, smpl)
|
||||
continue
|
||||
} else if evalData.SendUnmatched {
|
||||
// Sanitise the series points to remove any NaN or Inf values
|
||||
series.Points = removeGroupinSetPoints(series)
|
||||
if len(series.Points) == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -255,23 +253,13 @@ func (b BasicRuleThreshold) Validate() error {
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (b BasicRuleThreshold) matchesRecoveryThreshold(series v3.Series, ruleUnit string) (Sample, bool) {
|
||||
func (b BasicRuleThreshold) matchesRecoveryThreshold(series *v3.Series, ruleUnit string) (Sample, bool) {
|
||||
return b.shouldAlertWithTarget(series, b.recoveryTarget(ruleUnit))
|
||||
}
|
||||
func (b BasicRuleThreshold) shouldAlert(series v3.Series, ruleUnit string) (Sample, bool) {
|
||||
func (b BasicRuleThreshold) shouldAlert(series *v3.Series, ruleUnit string) (Sample, bool) {
|
||||
return b.shouldAlertWithTarget(series, b.target(ruleUnit))
|
||||
}
|
||||
|
||||
func removeGroupinSetPoints(series v3.Series) []v3.Point {
|
||||
var result []v3.Point
|
||||
for _, s := range series.Points {
|
||||
if s.Timestamp >= 0 && !math.IsNaN(s.Value) && !math.IsInf(s.Value, 0) {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// PrepareSampleLabelsForRule prepares the labels for the sample to be used in the alerting.
|
||||
// It accepts seriesLabels and thresholdName as input and returns the labels with the threshold name label added.
|
||||
func PrepareSampleLabelsForRule(seriesLabels map[string]string, thresholdName string) (lbls labels.Labels) {
|
||||
@@ -284,13 +272,10 @@ func PrepareSampleLabelsForRule(seriesLabels map[string]string, thresholdName st
|
||||
return lb.Labels()
|
||||
}
|
||||
|
||||
func (b BasicRuleThreshold) shouldAlertWithTarget(series v3.Series, target float64) (Sample, bool) {
|
||||
func (b BasicRuleThreshold) shouldAlertWithTarget(series *v3.Series, target float64) (Sample, bool) {
|
||||
var shouldAlert bool
|
||||
var alertSmpl Sample
|
||||
lbls := PrepareSampleLabelsForRule(series.Labels, b.Name)
|
||||
|
||||
series.Points = removeGroupinSetPoints(series)
|
||||
|
||||
// nothing to evaluate
|
||||
if len(series.Points) == 0 {
|
||||
return alertSmpl, false
|
||||
|
||||
@@ -270,7 +270,7 @@ func TestBasicRuleThresholdEval_UnitConversion(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
thresholds := BasicRuleThresholds{tt.threshold}
|
||||
vector, err := thresholds.Eval(tt.series, tt.ruleUnit, EvalData{})
|
||||
vector, err := thresholds.Eval(&tt.series, tt.ruleUnit, EvalData{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
alert := len(vector) > 0
|
||||
|
||||
Reference in New Issue
Block a user