diff --git a/pkg/query-service/app/clickhouseReader/reader.go b/pkg/query-service/app/clickhouseReader/reader.go index 2478a287ae..c8377fa43c 100644 --- a/pkg/query-service/app/clickhouseReader/reader.go +++ b/pkg/query-service/app/clickhouseReader/reader.go @@ -5113,7 +5113,14 @@ WHERE metric_name = ?;`, signozMetricDBName, signozTSTableNameV41Week) return timeSeriesCount, nil } -func (r *ClickHouseReader) GetAttributesForMetricName(ctx context.Context, metricName string, start, end *int64) (*[]metrics_explorer.Attribute, *model.ApiError) { +func (r *ClickHouseReader) GetAttributesForMetricName(ctx context.Context, metricName string, start, end *int64, filters *v3.FilterSet) (*[]metrics_explorer.Attribute, *model.ApiError) { + whereClause := "" + if filters != nil { + conditions, _ := utils.BuildFilterConditions(filters, "t") + if conditions != nil { + whereClause = "AND " + strings.Join(conditions, " AND ") + } + } const baseQueryTemplate = ` SELECT kv.1 AS key, @@ -5121,7 +5128,7 @@ SELECT length(groupUniqArray(10000)(kv.2)) AS valueCount FROM %s.%s ARRAY JOIN arrayFilter(x -> NOT startsWith(x.1, '__'), JSONExtractKeysAndValuesRaw(labels)) AS kv -WHERE metric_name = ? AND __normalized=true` +WHERE metric_name = ? AND __normalized=true %s` var args []interface{} args = append(args, metricName) @@ -5135,7 +5142,7 @@ WHERE metric_name = ? AND __normalized=true` tableName = signozTSTableNameV41Week } - query := fmt.Sprintf(baseQueryTemplate, signozMetricDBName, tableName) + query := fmt.Sprintf(baseQueryTemplate, signozMetricDBName, tableName, whereClause) if start != nil && end != nil { query += " AND unix_milli BETWEEN ? AND ?" @@ -5958,6 +5965,13 @@ func (r *ClickHouseReader) GetInspectMetricsFingerprints(ctx context.Context, at jsonExtracts = append(jsonExtracts, fmt.Sprintf("JSONExtractString(labels, '%s') AS %s", attr, keyAlias)) groupBys = append(groupBys, keyAlias) } + + conditions, _ := utils.BuildFilterConditions(&req.Filters, "") + whereClause := "" + if len(conditions) > 0 { + whereClause = "AND " + strings.Join(conditions, " AND ") + } + start, end, tsTable, _ := utils.WhichTSTableToUse(req.Start, req.End) query := fmt.Sprintf(` SELECT @@ -5970,12 +5984,14 @@ FROM FROM %s.%s WHERE metric_name = ? AND unix_milli BETWEEN ? AND ? + %s ) GROUP BY %s ORDER BY length(fingerprints) DESC, rand() LIMIT 40`, // added rand to get diff value every time we run this query strings.Join(jsonExtracts, ", "), signozMetricDBName, tsTable, + whereClause, strings.Join(groupBys, ", ")) valueCtx := context.WithValue(ctx, "clickhouse_max_threads", constants.MetricsExplorerClickhouseThreads) rows, err := r.db.Query(valueCtx, query, @@ -5991,20 +6007,26 @@ LIMIT 40`, // added rand to get diff value every time we run this query var fingerprints []string for rows.Next() { // Create dynamic scanning based on number of attributes - var fingerprintsList []string + var batch []string - if err := rows.Scan(&fingerprintsList); err != nil { + if err := rows.Scan(&batch); err != nil { return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} } - if len(fingerprints) == 0 || len(fingerprints)+len(fingerprintsList) < 40 { - fingerprints = append(fingerprints, fingerprintsList...) - } - - if len(fingerprints) > 40 { + remaining := 40 - len(fingerprints) + if remaining <= 0 { break } + // if this batch would overshoot, only take as many as we need + if len(batch) > remaining { + fingerprints = append(fingerprints, batch[:remaining]...) + break + } + + // otherwise take the whole batch and keep going + fingerprints = append(fingerprints, batch...) + } if err := rows.Err(); err != nil { diff --git a/pkg/query-service/app/metricsexplorer/summary.go b/pkg/query-service/app/metricsexplorer/summary.go index 8b19dfef63..e97643b3ac 100644 --- a/pkg/query-service/app/metricsexplorer/summary.go +++ b/pkg/query-service/app/metricsexplorer/summary.go @@ -147,7 +147,7 @@ func (receiver *SummaryService) GetMetricsSummary(ctx context.Context, orgID val }) g.Go(func() error { - attributes, err := receiver.reader.GetAttributesForMetricName(ctx, metricName, nil, nil) + attributes, err := receiver.reader.GetAttributesForMetricName(ctx, metricName, nil, nil, nil) if err != nil { return err } @@ -475,7 +475,7 @@ func (receiver *SummaryService) GetInspectMetrics(ctx context.Context, params *m // Run the two queries concurrently using the derived context. g.Go(func() error { - attrs, apiErr := receiver.reader.GetAttributesForMetricName(egCtx, params.MetricName, ¶ms.Start, ¶ms.End) + attrs, apiErr := receiver.reader.GetAttributesForMetricName(egCtx, params.MetricName, ¶ms.Start, ¶ms.End, ¶ms.Filters) if apiErr != nil { return apiErr } diff --git a/pkg/query-service/interfaces/interface.go b/pkg/query-service/interfaces/interface.go index 4b3a5f24f6..55af995e67 100644 --- a/pkg/query-service/interfaces/interface.go +++ b/pkg/query-service/interfaces/interface.go @@ -122,7 +122,7 @@ type Reader interface { GetMetricsLastReceived(ctx context.Context, metricName string) (int64, *model.ApiError) GetTotalTimeSeriesForMetricName(ctx context.Context, metricName string) (uint64, *model.ApiError) GetActiveTimeSeriesForMetricName(ctx context.Context, metricName string, duration time.Duration) (uint64, *model.ApiError) - GetAttributesForMetricName(ctx context.Context, metricName string, start, end *int64) (*[]metrics_explorer.Attribute, *model.ApiError) + GetAttributesForMetricName(ctx context.Context, metricName string, start, end *int64, set *v3.FilterSet) (*[]metrics_explorer.Attribute, *model.ApiError) ListSummaryMetrics(ctx context.Context, orgID valuer.UUID, req *metrics_explorer.SummaryListMetricsRequest) (*metrics_explorer.SummaryListMetricsResponse, *model.ApiError)