74 lines
2.3 KiB
Go
74 lines
2.3 KiB
Go
|
package postprocess
|
||
|
|
||
|
import (
|
||
|
"github.com/SigNoz/govaluate"
|
||
|
"go.signoz.io/signoz/pkg/query-service/common"
|
||
|
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
||
|
)
|
||
|
|
||
|
func StepIntervalForFunction(params *v3.QueryRangeParamsV3, query string) int64 {
|
||
|
q := params.CompositeQuery.BuilderQueries[query]
|
||
|
if q.QueryName != q.Expression {
|
||
|
expression, _ := govaluate.NewEvaluableExpressionWithFunctions(q.Expression, EvalFuncs())
|
||
|
steps := []int64{}
|
||
|
for _, v := range expression.Vars() {
|
||
|
steps = append(steps, params.CompositeQuery.BuilderQueries[v].StepInterval)
|
||
|
}
|
||
|
return common.LCMList(steps)
|
||
|
}
|
||
|
return q.StepInterval
|
||
|
}
|
||
|
|
||
|
func fillGap(series *v3.Series, start, end, step int64) *v3.Series {
|
||
|
v := make(map[int64]float64)
|
||
|
for _, point := range series.Points {
|
||
|
v[point.Timestamp] = point.Value
|
||
|
}
|
||
|
|
||
|
// For all the values from start to end, find the timestamps
|
||
|
// that don't have value and add zero point
|
||
|
start = start - (start % (step * 1000))
|
||
|
for i := start; i <= end; i += step * 1000 {
|
||
|
if _, ok := v[i]; !ok {
|
||
|
v[i] = 0
|
||
|
}
|
||
|
}
|
||
|
newSeries := &v3.Series{
|
||
|
Labels: series.Labels,
|
||
|
LabelsArray: series.LabelsArray,
|
||
|
Points: make([]v3.Point, 0),
|
||
|
}
|
||
|
for i := start; i <= end; i += step * 1000 {
|
||
|
newSeries.Points = append(newSeries.Points, v3.Point{Timestamp: i, Value: v[i]})
|
||
|
}
|
||
|
return newSeries
|
||
|
}
|
||
|
|
||
|
// TODO(srikanthccv): can WITH FILL be perfect substitute for all cases https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
|
||
|
func FillGaps(results []*v3.Result, params *v3.QueryRangeParamsV3) {
|
||
|
if params.CompositeQuery.PanelType != v3.PanelTypeGraph {
|
||
|
return
|
||
|
}
|
||
|
for _, result := range results {
|
||
|
// A `result` item in `results` contains the query result for individual query.
|
||
|
// If there are no series in the result, we add empty series and `fillGap` adds all zeros
|
||
|
if len(result.Series) == 0 {
|
||
|
result.Series = []*v3.Series{
|
||
|
{
|
||
|
Labels: make(map[string]string),
|
||
|
LabelsArray: make([]map[string]string, 0),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
builderQueries := params.CompositeQuery.BuilderQueries
|
||
|
if builderQueries != nil {
|
||
|
// The values should be added at the intervals of `step`
|
||
|
step := StepIntervalForFunction(params, result.QueryName)
|
||
|
for idx := range result.Series {
|
||
|
result.Series[idx] = fillGap(result.Series[idx], params.Start, params.End, step)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|