mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-08 10:59:04 +08:00
fix: interpret missing point as zero value in formula evaluation (#4668)
This commit is contained in:
parent
5a2d729ba9
commit
b4d12966f3
@ -87,23 +87,6 @@ func joinAndCalculate(results []*v3.Result, uniqueLabelSet map[string]string, ex
|
||||
}
|
||||
}
|
||||
|
||||
vars := expression.Vars()
|
||||
var doesNotHaveAllVars bool
|
||||
for _, v := range vars {
|
||||
if _, ok := seriesMap[v]; !ok {
|
||||
doesNotHaveAllVars = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// There is no series that matches the label set from all queries
|
||||
// TODO: Does the lack of a series from one query mean that the result should be nil?
|
||||
// Or should we interpret the series as having a value of 0 at all timestamps?
|
||||
// The current behaviour with ClickHouse is to show no data
|
||||
if doesNotHaveAllVars {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
resultSeries := &v3.Series{
|
||||
Labels: uniqueLabelSet,
|
||||
}
|
||||
|
@ -235,7 +235,39 @@ func TestProcessResults(t *testing.T) {
|
||||
},
|
||||
},
|
||||
want: &v3.Result{
|
||||
Series: []*v3.Series{},
|
||||
Series: []*v3.Series{
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"service_name": "frontend",
|
||||
"operation": "GET /api",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 10,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"service_name": "redis",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 30,
|
||||
},
|
||||
{
|
||||
Timestamp: 3,
|
||||
Value: 40,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -350,6 +382,21 @@ func TestProcessResultsErrorRate(t *testing.T) {
|
||||
},
|
||||
want: &v3.Result{
|
||||
Series: []*v3.Series{
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"service_name": "frontend",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"service_name": "redis",
|
||||
@ -365,6 +412,21 @@ func TestProcessResultsErrorRate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"service_name": "route",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -906,14 +968,7 @@ func TestFormula(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &v3.Result{},
|
||||
},
|
||||
{
|
||||
name: "Group keys on both sides are overlapping but do not match exactly",
|
||||
expression: "A/B",
|
||||
results: []*v3.Result{
|
||||
{
|
||||
QueryName: "A",
|
||||
want: &v3.Result{
|
||||
Series: []*v3.Series{
|
||||
{
|
||||
Labels: map[string]string{
|
||||
@ -923,23 +978,23 @@ func TestFormula(t *testing.T) {
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 10,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 20,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: 40,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: 50,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 7,
|
||||
Value: 70,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -951,88 +1006,81 @@ func TestFormula(t *testing.T) {
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 12,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 45,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 3,
|
||||
Value: 30,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: 40,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: 50,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
QueryName: "B",
|
||||
Series: []*v3.Series{
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"os.type": "linux",
|
||||
"state": "running",
|
||||
"host_name": "ip-10-420-69-1",
|
||||
"state": "not_running_chalamet",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 22,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 65,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 3,
|
||||
Value: 30,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: 40,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: 50,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"os.type": "windows",
|
||||
"host_name": "ip-10-420-69-2",
|
||||
"state": "busy",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 22,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 65,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: 40,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: 50,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &v3.Result{},
|
||||
},
|
||||
{
|
||||
name: "Group keys on the left side are a superset of the right side",
|
||||
expression: "A/B",
|
||||
@ -1193,6 +1241,59 @@ func TestFormula(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"host_name": "ip-10-420-69-2",
|
||||
"state": "idle",
|
||||
"os.type": "linux",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 3,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: math.Inf(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Labels: map[string]string{
|
||||
"state": "busy",
|
||||
"os.type": "linux",
|
||||
},
|
||||
Points: []v3.Point{
|
||||
{
|
||||
Timestamp: 1,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 2,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 4,
|
||||
Value: 0,
|
||||
},
|
||||
{
|
||||
Timestamp: 5,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1454,18 +1555,22 @@ func TestFormula(t *testing.T) {
|
||||
expression, err := govaluate.NewEvaluableExpression(tt.expression)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing expression: %v", err)
|
||||
return
|
||||
}
|
||||
got, err := processResults(tt.results, expression)
|
||||
if err != nil {
|
||||
t.Errorf("Error processing results: %v", err)
|
||||
return
|
||||
}
|
||||
if len(got.Series) != len(tt.want.Series) {
|
||||
t.Errorf("processResults(): number of series - got = %v, want %v", len(got.Series), len(tt.want.Series))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range got.Series {
|
||||
if len(got.Series[i].Points) != len(tt.want.Series[i].Points) {
|
||||
t.Errorf("processResults(): number of points - got = %v, want %v", len(got.Series[i].Points), len(tt.want.Series[i].Points))
|
||||
return
|
||||
}
|
||||
for j := range got.Series[i].Points {
|
||||
if got.Series[i].Points[j].Value != tt.want.Series[i].Points[j].Value {
|
||||
|
Loading…
x
Reference in New Issue
Block a user