Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update query builder to support spatial aggregations and functions #4569

Merged
merged 30 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e0642fd
feat: update query builder to support spatial aggregations and functions
YounixM Feb 18, 2024
e874439
feat: handle query function - value
YounixM Feb 18, 2024
7ca2589
fix: rename guage to gauge, fix styles
YounixM Feb 18, 2024
0dbc483
feat: add shorcuts to dashboard and improve ui
YounixM Feb 18, 2024
f80a76b
feat: dashboard - add panel - ui updates
YounixM Feb 18, 2024
a64c68b
feat: update functions ui and restrict max 3 functions
YounixM Feb 19, 2024
8cb4a79
chore: resolve conflicts
srikanthccv Feb 13, 2024
c6482fe
chore: several fixes
srikanthccv Feb 19, 2024
ed1e172
feat: update dashboard default version to v3
YounixM Feb 19, 2024
14fcc51
feat: update logsConnectionStatus query range payload to add v4 variable
YounixM Feb 19, 2024
ea415a4
feat: show functions and space aggregation in v4 only
YounixM Feb 20, 2024
5e68e01
feat: handle duplicate labels in charts tooltip
YounixM Feb 20, 2024
4dc1e7f
fix: update the spaceAggregation element key
YounixM Feb 21, 2024
244b367
fix: update the spaceAggregation upon time Aggregation change
YounixM Feb 21, 2024
b04dead
chore: fix the aggregate attributes validation
srikanthccv Feb 21, 2024
2638d45
feat: show functions for metrics based alerts v4
YounixM Feb 22, 2024
0441400
Merge branch 'develop' into metrics-qb-change
srikanthccv Feb 27, 2024
9f4fa2f
feat: update functions styles
YounixM Feb 27, 2024
1eb7f3e
Merge branch 'develop' into metrics-qb-change
srikanthccv Feb 27, 2024
8da74c4
chore: add v4 support for rules
srikanthccv Feb 20, 2024
9ab75bc
feat: update create panels list
YounixM Feb 28, 2024
3bfbd36
Merge branch 'develop' into metrics-qb-change
YounixM Feb 28, 2024
3fa5aea
Merge branch 'develop' into metrics-qb-change
srikanthccv Feb 28, 2024
f47ff43
feat: add bar chart option in dashboard
YounixM Feb 28, 2024
680d1d9
chore: remove print and update version
srikanthccv Feb 28, 2024
4606598
feat: handle v3/v4 version to query-range api call for metrics dashbo…
YounixM Feb 28, 2024
78a5614
Merge branch 'develop' into metrics-qb-change
srikanthccv Feb 29, 2024
53a7681
feat: handle version incase of create alerts from dashboard
YounixM Feb 29, 2024
5c2d2ee
feat: show reduce to options in table and value panel types
YounixM Mar 1, 2024
462b059
Merge branch 'develop' into metrics-qb-change
srikanthccv Mar 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: several fixes
  • Loading branch information
srikanthccv authored and YounixM committed Feb 22, 2024
commit c6482fe588a40c097aa080bdaf6f130b4b63eec8
2 changes: 1 addition & 1 deletion frontend/src/constants/queryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export const initialQueryBuilderFormValues: IBuilderQuery = {
orderBy: [],
groupBy: [],
legend: '',
reduceTo: 'sum',
reduceTo: 'avg',
};

const initialQueryBuilderFormLogsValues: IBuilderQuery = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const getQueryBuilderQueries = ({
items: filterItems[index],
op: 'AND',
},
reduceTo: 'sum',
reduceTo: 'avg',
dataSource,
};

Expand Down Expand Up @@ -86,7 +86,7 @@ export const getQueryBuilderQuerieswithFormula = ({
aggregateAttribute: autocompleteData[index],
queryName: alphabet[index],
expression: alphabet[index],
reduceTo: 'sum',
reduceTo: 'avg',
filters: {
items: additionalItems[index],
op: 'AND',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const getTraceToLogsQuery = (
legend: '',
orderBy: [],
queryName: 'A',
reduceTo: 'min',
reduceTo: 'avg',
stepInterval: getStep({
start: minTime,
end: maxTime,
Expand Down
2 changes: 1 addition & 1 deletion frontend/tests/dashboards/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const insertWidgetIdInResponse = (widgetID: string): any => ({
limit: null,
orderBy: [],
queryName: 'A',
reduceTo: 'sum',
reduceTo: 'avg',
stepInterval: 60,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "sum",
"reduceTo": "avg",
"stepInterval": 60
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "sum",
"reduceTo": "avg",
"stepInterval": 60
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"order": "desc"
}
],
"reduceTo": "sum"
"reduceTo": "avg"
}
},
"panelType": "table",
Expand Down
22 changes: 15 additions & 7 deletions pkg/query-service/app/clickhouseReader/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3975,7 +3975,7 @@ func (r *ClickHouseReader) GetMetricAggregateAttributes(ctx context.Context, req
var rows driver.Rows
var response v3.AggregateAttributeResponse

query = fmt.Sprintf("SELECT DISTINCT metric_name, type, is_monotonic from %s.%s WHERE metric_name ILIKE $1", signozMetricDBName, signozTSTableNameV41Day)
query = fmt.Sprintf("SELECT metric_name, type, is_monotonic, temporality FROM %s.%s WHERE metric_name ILIKE $1 GROUP BY metric_name, type, is_monotonic, temporality", signozMetricDBName, signozTSTableNameV41Day)
if req.Limit != 0 {
query = query + fmt.Sprintf(" LIMIT %d;", req.Limit)
}
Expand All @@ -3987,22 +3987,30 @@ func (r *ClickHouseReader) GetMetricAggregateAttributes(ctx context.Context, req
}
defer rows.Close()

var metricName, typ string
seen := make(map[string]struct{})

var metricName, typ, temporality string
var isMonotonic bool
for rows.Next() {
if err := rows.Scan(&metricName, &typ, &isMonotonic); err != nil {
if err := rows.Scan(&metricName, &typ, &isMonotonic, &temporality); err != nil {
return nil, fmt.Errorf("error while scanning rows: %s", err.Error())
}
// unlike traces/logs `tag`/`resource` type, the `Type` will be metric type
if typ == "Sum" && !isMonotonic {
// Non-monotonic cumulative sums are treated as gauges
if typ == "Sum" && !isMonotonic && temporality == string(v3.Cumulative) {
typ = "Gauge"
}
// unlike traces/logs `tag`/`resource` type, the `Type` will be metric type
key := v3.AttributeKey{
Key: metricName,
DataType: v3.AttributeKeyDataTypeFloat64,
Type: v3.AttributeKeyType(typ),
IsColumn: true,
}
// remove duplicates
if _, ok := seen[metricName+typ]; ok {
continue
}
seen[metricName+typ] = struct{}{}
response.AttributeKeys = append(response.AttributeKeys, key)
}

Expand All @@ -4017,7 +4025,7 @@ func (r *ClickHouseReader) GetMetricAttributeKeys(ctx context.Context, req *v3.F
var response v3.FilterAttributeKeyResponse

// skips the internal attributes i.e attributes starting with __
query = fmt.Sprintf("SELECT DISTINCT arrayJoin(tagKeys) as distinctTagKey from (SELECT DISTINCT(JSONExtractKeys(labels)) tagKeys from %s.%s WHERE metric_name=$1 AND unix_milli >= $2) WHERE distinctTagKey ILIKE $3 AND distinctTagKey NOT LIKE '\\_\\_%%'", signozMetricDBName, signozTSTableNameV41Day)
query = fmt.Sprintf("SELECT arrayJoin(tagKeys) AS distinctTagKey FROM (SELECT JSONExtractKeys(labels) AS tagKeys FROM %s.%s WHERE metric_name=$1 AND unix_milli >= $2 GROUP BY tagKeys) WHERE distinctTagKey ILIKE $3 AND distinctTagKey NOT LIKE '\\_\\_%%' GROUP BY distinctTagKey", signozMetricDBName, signozTSTableNameV41Day)
if req.Limit != 0 {
query = query + fmt.Sprintf(" LIMIT %d;", req.Limit)
}
Expand Down Expand Up @@ -4052,7 +4060,7 @@ func (r *ClickHouseReader) GetMetricAttributeValues(ctx context.Context, req *v3
var rows driver.Rows
var attributeValues v3.FilterAttributeValueResponse

query = fmt.Sprintf("SELECT DISTINCT(JSONExtractString(labels, $1)) from %s.%s WHERE metric_name=$2 AND JSONExtractString(labels, $3) ILIKE $4 AND unix_milli >= $5", signozMetricDBName, signozTSTableNameV41Day)
query = fmt.Sprintf("SELECT JSONExtractString(labels, $1) AS tagValue FROM %s.%s WHERE metric_name=$2 AND JSONExtractString(labels, $3) ILIKE $4 AND unix_milli >= $5 GROUP BY tagValue", signozMetricDBName, signozTSTableNameV41Day)
if req.Limit != 0 {
query = query + fmt.Sprintf(" LIMIT %d;", req.Limit)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/query-service/app/limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func applyMetricLimit(results []*v3.Result, queryRangeParams *v3.QueryRangeParam
limit := builderQueries[result.QueryName].Limit

orderByList := builderQueries[result.QueryName].OrderBy
if limit > 0 {
{
YounixM marked this conversation as resolved.
Show resolved Hide resolved
if len(orderByList) == 0 {
// If no orderBy is specified, sort by value in descending order
orderByList = []v3.OrderBy{{ColumnName: constants.SigNozOrderByValue, Order: "desc"}}
Expand Down
6 changes: 4 additions & 2 deletions pkg/query-service/app/metrics/v4/query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func PrepareMetricQuery(start, end int64, queryType v3.QueryType, panelType v3.P

var quantile float64

if v3.IsPercentileOperator(mq.SpaceAggregation) {
if v3.IsPercentileOperator(mq.SpaceAggregation) &&
mq.AggregateAttribute.Type != v3.AttributeKeyType(v3.MetricTypeExponentialHistogram) {
quantile = v3.GetPercentileFromOperator(mq.SpaceAggregation)
// If quantile is set, we need to group by le
// and set the space aggregation to sum
Expand Down Expand Up @@ -81,7 +82,8 @@ func PrepareMetricQuery(start, end int64, queryType v3.QueryType, panelType v3.P
groupBy := helpers.GroupByAttributeKeyTags(groupByWithoutLe...)
orderBy := helpers.OrderByAttributeKeyTags(mq.OrderBy, groupByWithoutLe)

if quantile != 0 {
// fixed-bucket histogram quantiles are calculated with UDF
if quantile != 0 && mq.AggregateAttribute.Type != v3.AttributeKeyType(v3.MetricTypeExponentialHistogram) {
query = fmt.Sprintf(`SELECT %s, histogramQuantile(arrayMap(x -> toFloat64(x), groupArray(le)), groupArray(value), %.3f) as value FROM (%s) GROUP BY %s ORDER BY %s`, groupBy, quantile, query, groupBy, orderBy)
}

Expand Down
38 changes: 19 additions & 19 deletions pkg/query-service/app/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,25 @@ func ParseQueryRangeParams(r *http.Request) (*v3.QueryRangeParamsV3, *model.ApiE
}
}

var timeShiftBy int64
if len(query.Functions) > 0 {
for idx := range query.Functions {
function := &query.Functions[idx]
if function.Name == v3.FunctionNameTimeShift {
// move the function to the beginning of the list
// so any other function can use the shifted time
var fns []v3.Function
fns = append(fns, *function)
fns = append(fns, query.Functions[:idx]...)
fns = append(fns, query.Functions[idx+1:]...)
query.Functions = fns
timeShiftBy = int64(function.Args[0].(float64))
break
}
}
}
query.ShiftBy = timeShiftBy

YounixM marked this conversation as resolved.
Show resolved Hide resolved
if query.Filters == nil || len(query.Filters.Items) == 0 {
continue
}
Expand All @@ -1045,25 +1064,6 @@ func ParseQueryRangeParams(r *http.Request) (*v3.QueryRangeParamsV3, *model.ApiE
}
}
}

var timeShiftBy int64
if len(query.Functions) > 0 {
for idx := range query.Functions {
function := &query.Functions[idx]
if function.Name == v3.FunctionNameTimeShift {
// move the function to the beginning of the list
// so any other function can use the shifted time
var fns []v3.Function
fns = append(fns, *function)
fns = append(fns, query.Functions[:idx]...)
fns = append(fns, query.Functions[idx+1:]...)
query.Functions = fns
timeShiftBy = int64(function.Args[0].(float64))
break
}
}
}
query.ShiftBy = timeShiftBy
}
}
queryRangeParams.Variables = formattedVars
Expand Down
3 changes: 1 addition & 2 deletions pkg/query-service/common/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ func AdjustedMetricTimeRange(start, end, step int64, aggregaOperator v3.TimeAggr

func PastDayRoundOff() int64 {
now := time.Now().UnixMilli()
pastDay := now - (now % (time.Hour.Milliseconds() * 24))
return pastDay
return int64(math.Floor(float64(now)/float64(time.Hour.Milliseconds()*24))) * time.Hour.Milliseconds() * 24
}
45 changes: 37 additions & 8 deletions pkg/query-service/model/v3/v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,11 @@ const (
SpaceAggregationMin SpaceAggregation = "min"
SpaceAggregationMax SpaceAggregation = "max"
SpaceAggregationCount SpaceAggregation = "count"
SpaceAggregationPercentile50 SpaceAggregation = "percentile_50"
SpaceAggregationPercentile75 SpaceAggregation = "percentile_75"
SpaceAggregationPercentile90 SpaceAggregation = "percentile_90"
SpaceAggregationPercentile95 SpaceAggregation = "percentile_95"
SpaceAggregationPercentile99 SpaceAggregation = "percentile_99"
SpaceAggregationPercentile50 SpaceAggregation = "p50"
SpaceAggregationPercentile75 SpaceAggregation = "p75"
SpaceAggregationPercentile90 SpaceAggregation = "p90"
SpaceAggregationPercentile95 SpaceAggregation = "p95"
SpaceAggregationPercentile99 SpaceAggregation = "p99"
)

func (s SpaceAggregation) Validate() error {
Expand Down Expand Up @@ -659,8 +659,11 @@ func (b *BuilderQuery) Validate() error {
return fmt.Errorf("aggregate operator is invalid: %w", err)
}
} else {
if err := b.TimeAggregation.Validate(); err != nil {
return fmt.Errorf("time aggregation is invalid: %w", err)
// the time aggregation is not needed for percentile operators
if !IsPercentileOperator(b.SpaceAggregation) {
if err := b.TimeAggregation.Validate(); err != nil {
return fmt.Errorf("time aggregation is invalid: %w", err)
}
}

if err := b.SpaceAggregation.Validate(); err != nil {
Expand Down Expand Up @@ -723,13 +726,30 @@ func (b *BuilderQuery) Validate() error {
if len(function.Args) == 0 {
return fmt.Errorf("timeShiftBy param missing in query")
}
_, ok := function.Args[0].(float64)
if !ok {
// if string, attempt to convert to float
timeShiftBy, err := strconv.ParseFloat(function.Args[0].(string), 64)
if err != nil {
return fmt.Errorf("timeShiftBy param should be a number")
}
function.Args[0] = timeShiftBy
}
YounixM marked this conversation as resolved.
Show resolved Hide resolved
} else if function.Name == FunctionNameEWMA3 ||
function.Name == FunctionNameEWMA5 ||
function.Name == FunctionNameEWMA7 {
if len(function.Args) == 0 {
return fmt.Errorf("alpha param missing in query")
}
alpha := function.Args[0].(float64)
alpha, ok := function.Args[0].(float64)
if !ok {
// if string, attempt to convert to float
alpha, err := strconv.ParseFloat(function.Args[0].(string), 64)
if err != nil {
return fmt.Errorf("alpha param should be a float")
}
function.Args[0] = alpha
}
YounixM marked this conversation as resolved.
Show resolved Hide resolved
if alpha < 0 || alpha > 1 {
return fmt.Errorf("alpha param should be between 0 and 1")
}
Expand All @@ -740,6 +760,15 @@ func (b *BuilderQuery) Validate() error {
if len(function.Args) == 0 {
return fmt.Errorf("threshold param missing in query")
}
_, ok := function.Args[0].(float64)
if !ok {
// if string, attempt to convert to float
threshold, err := strconv.ParseFloat(function.Args[0].(string), 64)
if err != nil {
return fmt.Errorf("threshold param should be a float")
}
function.Args[0] = threshold
}
YounixM marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down