diff --git a/docs/sources/developers/kinds/composable/prometheusdataquery/schema-reference.md b/docs/sources/developers/kinds/composable/prometheusdataquery/schema-reference.md
new file mode 100644
index 00000000000..2645ed1d5c9
--- /dev/null
+++ b/docs/sources/developers/kinds/composable/prometheusdataquery/schema-reference.md
@@ -0,0 +1,44 @@
+---
+keywords:
+ - grafana
+ - schema
+title: PrometheusDataQuery kind
+---
+> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
+
+## PrometheusDataQuery
+
+#### Maturity: [experimental](../../../maturity/#experimental)
+#### Version: 0.0
+
+
+
+It extends [DataQuery](#dataquery).
+
+| Property | Type | Required | Description |
+|--------------|---------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `expr` | string | **Yes** | The actual expression/query that will be evaluated by Prometheus |
+| `refId` | string | **Yes** | *(Inherited from [DataQuery](#dataquery))*
A unique identifier for the query within the list of targets.
In server side expressions, the refId is used as a variable name to identify results.
By default, the UI will assign A->Z; however setting meaningful names may be useful. |
+| `datasource` | | No | *(Inherited from [DataQuery](#dataquery))*
For mixed data sources the selected datasource is on the query level.
For non mixed scenarios this is undefined.
TODO find a better way to do this ^ that's friendly to schema
TODO this shouldn't be unknown but DataSourceRef | null |
+| `editorMode` | string | No | Possible values are: `code`, `builder`. |
+| `exemplar` | boolean | No | Execute an additional query to identify interesting raw samples relevant for the given expr |
+| `format` | string | No | Possible values are: `time_series`, `table`, `heatmap`. |
+| `hide` | boolean | No | *(Inherited from [DataQuery](#dataquery))*
true if query is disabled (ie should not be returned to the dashboard)
Note this does not always imply that the query should not be executed since
the results from a hidden query may be used as the input to other queries (SSE etc) |
+| `instant` | boolean | No | Returns only the latest value that Prometheus has scraped for the requested time series |
+| `queryType` | string | No | *(Inherited from [DataQuery](#dataquery))*
Specify the query flavor
TODO make this required and give it a default |
+| `range` | boolean | No | Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series |
+
+### DataQuery
+
+These are the common properties available to all queries in all datasources.
+Specific implementations will *extend* this interface, adding the required
+properties for the given context.
+
+| Property | Type | Required | Description |
+|--------------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `refId` | string | **Yes** | A unique identifier for the query within the list of targets.
In server side expressions, the refId is used as a variable name to identify results.
By default, the UI will assign A->Z; however setting meaningful names may be useful. |
+| `datasource` | | No | For mixed data sources the selected datasource is on the query level.
For non mixed scenarios this is undefined.
TODO find a better way to do this ^ that's friendly to schema
TODO this shouldn't be unknown but DataSourceRef | null |
+| `hide` | boolean | No | true if query is disabled (ie should not be returned to the dashboard)
Note this does not always imply that the query should not be executed since
the results from a hidden query may be used as the input to other queries (SSE etc) |
+| `queryType` | string | No | Specify the query flavor
TODO make this required and give it a default |
+
+
diff --git a/pkg/kindsys/report.json b/pkg/kindsys/report.json
index 98f0af2335c..0627ecec5fc 100644
--- a/pkg/kindsys/report.json
+++ b/pkg/kindsys/report.json
@@ -1346,7 +1346,9 @@
},
"prometheusdataquery": {
"category": "composable",
- "codeowners": [],
+ "codeowners": [
+ "grafana/observability-metrics"
+ ],
"currentVersion": [
0,
0
@@ -1354,13 +1356,13 @@
"grafanaMaturityCount": 0,
"lineageIsGroup": false,
"links": {
- "docs": "n/a",
- "go": "n/a",
- "schema": "n/a",
- "ts": "n/a"
+ "docs": "https://grafana.com/docs/grafana/next/developers/kinds/composable/prometheusdataquery/schema-reference",
+ "go": "https://github.com/grafana/grafana/tree/main/pkg/tsdb/prometheus/kinds/dataquery/types_dataquery_gen.go",
+ "schema": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/prometheus/dataquery.cue",
+ "ts": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/prometheus/dataquery.gen.ts"
},
"machineName": "prometheusdataquery",
- "maturity": "planned",
+ "maturity": "experimental",
"name": "PrometheusDataQuery",
"pluralMachineName": "prometheusdataquerys",
"pluralName": "PrometheusDataQuerys",
@@ -2053,6 +2055,7 @@
"parcadataquery",
"phlaredataquery",
"piechartpanelcfg",
+ "prometheusdataquery",
"statetimelinepanelcfg",
"statpanelcfg",
"statushistorypanelcfg",
@@ -2062,7 +2065,7 @@
"textpanelcfg",
"xychartpanelcfg"
],
- "count": 26
+ "count": 27
},
"mature": {
"name": "mature",
@@ -2120,7 +2123,6 @@
"phlaredatasourcecfg",
"postgresqldataquery",
"postgresqldatasourcecfg",
- "prometheusdataquery",
"prometheusdatasourcecfg",
"query",
"queryhistory",
@@ -2134,7 +2136,7 @@
"zipkindataquery",
"zipkindatasourcecfg"
],
- "count": 46
+ "count": 45
},
"stable": {
"name": "stable",
diff --git a/pkg/tsdb/prometheus/kinds/dataquery/types_dataquery_gen.go b/pkg/tsdb/prometheus/kinds/dataquery/types_dataquery_gen.go
new file mode 100644
index 00000000000..4d00213adac
--- /dev/null
+++ b/pkg/tsdb/prometheus/kinds/dataquery/types_dataquery_gen.go
@@ -0,0 +1,89 @@
+// Code generated - EDITING IS FUTILE. DO NOT EDIT.
+//
+// Generated by:
+// public/app/plugins/gen.go
+// Using jennies:
+// PluginGoTypesJenny
+//
+// Run 'make gen-cue' from repository root to regenerate.
+
+package dataquery
+
+// Defines values for PromQueryFormat.
+const (
+ PromQueryFormatHeatmap PromQueryFormat = "heatmap"
+ PromQueryFormatTable PromQueryFormat = "table"
+ PromQueryFormatTimeSeries PromQueryFormat = "time_series"
+)
+
+// Defines values for EditorMode.
+const (
+ EditorModeBuilder EditorMode = "builder"
+ EditorModeCode EditorMode = "code"
+)
+
+// Defines values for Format.
+const (
+ FormatHeatmap Format = "heatmap"
+ FormatTable Format = "table"
+ FormatTimeSeries Format = "time_series"
+)
+
+// Defines values for QueryEditorMode.
+const (
+ QueryEditorModeBuilder QueryEditorMode = "builder"
+ QueryEditorModeCode QueryEditorMode = "code"
+)
+
+// PromQueryFormat defines model for PromQueryFormat.
+type PromQueryFormat string
+
+// PrometheusDataQuery defines model for PrometheusDataQuery.
+type PrometheusDataQuery struct {
+ // For mixed data sources the selected datasource is on the query level.
+ // For non mixed scenarios this is undefined.
+ // TODO find a better way to do this ^ that's friendly to schema
+ // TODO this shouldn't be unknown but DataSourceRef | null
+ Datasource *interface{} `json:"datasource,omitempty"`
+
+ // Specifies which editor is being used to prepare the query. It can be "code" or "builder"
+ EditorMode *EditorMode `json:"editorMode,omitempty"`
+
+ // Execute an additional query to identify interesting raw samples relevant for the given expr
+ Exemplar *bool `json:"exemplar,omitempty"`
+
+ // The actual expression/query that will be evaluated by Prometheus
+ Expr string `json:"expr"`
+
+ // Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"
+ Format *Format `json:"format,omitempty"`
+
+ // Hide true if query is disabled (ie should not be returned to the dashboard)
+ // Note this does not always imply that the query should not be executed since
+ // the results from a hidden query may be used as the input to other queries (SSE etc)
+ Hide *bool `json:"hide,omitempty"`
+
+ // Returns only the latest value that Prometheus has scraped for the requested time series
+ Instant *bool `json:"instant,omitempty"`
+
+ // Specify the query flavor
+ // TODO make this required and give it a default
+ QueryType *string `json:"queryType,omitempty"`
+
+ // Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series
+ Range *bool `json:"range,omitempty"`
+
+ // A unique identifier for the query within the list of targets.
+ // In server side expressions, the refId is used as a variable name to identify results.
+ // By default, the UI will assign A->Z; however setting meaningful names may be useful.
+ RefId string `json:"refId"`
+}
+
+// Specifies which editor is being used to prepare the query. It can be "code" or "builder"
+type EditorMode string
+
+// Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"
+type Format string
+
+// QueryEditorMode defines model for QueryEditorMode.
+type QueryEditorMode string
diff --git a/pkg/tsdb/prometheus/models/query.go b/pkg/tsdb/prometheus/models/query.go
index 233d8fddc50..741d6d4e8bc 100644
--- a/pkg/tsdb/prometheus/models/query.go
+++ b/pkg/tsdb/prometheus/models/query.go
@@ -8,8 +8,8 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
-
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
+ "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery"
)
// Internal interval and range variables
@@ -45,16 +45,14 @@ const (
var safeResolution = 11000
type QueryModel struct {
- Expr string `json:"expr"`
- LegendFormat string `json:"legendFormat"`
- Interval string `json:"interval"`
- IntervalMS int64 `json:"intervalMS"`
- StepMode string `json:"stepMode"`
- RangeQuery bool `json:"range"`
- InstantQuery bool `json:"instant"`
- ExemplarQuery bool `json:"exemplar"`
- IntervalFactor int64 `json:"intervalFactor"`
- UtcOffsetSec int64 `json:"utcOffsetSec"`
+ dataquery.PrometheusDataQuery
+ // The following properties may be part of the request payload, however they are not saved in panel JSON
+ // Timezone offset to align start & end time on backend
+ UtcOffsetSec int64 `json:"utcOffsetSec,omitempty"`
+ LegendFormat string `json:"legendFormat,omitempty"`
+ Interval string `json:"interval,omitempty"`
+ IntervalMs int64 `json:"intervalMs,omitempty"`
+ IntervalFactor int64 `json:"intervalFactor,omitempty"`
}
type TimeRange struct {
@@ -82,23 +80,36 @@ func Parse(query backend.DataQuery, timeInterval string, intervalCalculator inte
return nil, err
}
- //Final interval value
- interval, err := calculatePrometheusInterval(model, timeInterval, query, intervalCalculator)
+ // Final interval value
+ interval, err := calculatePrometheusInterval(model.Interval, timeInterval, model.IntervalMs, model.IntervalFactor, query, intervalCalculator)
if err != nil {
return nil, err
}
// Interpolate variables in expr
timeRange := query.TimeRange.To.Sub(query.TimeRange.From)
- expr := interpolateVariables(model, interval, timeRange, intervalCalculator, timeInterval)
- rangeQuery := model.RangeQuery
- if !model.InstantQuery && !model.RangeQuery {
+ expr := interpolateVariables(model.Expr, model.Interval, interval, timeRange, intervalCalculator, timeInterval)
+ var rangeQuery, instantQuery bool
+ if model.Instant == nil {
+ instantQuery = false
+ } else {
+ instantQuery = *model.Instant
+ }
+ if model.Range == nil {
+ rangeQuery = false
+ } else {
+ rangeQuery = *model.Range
+ }
+ if !instantQuery && !rangeQuery {
// In older dashboards, we were not setting range query param and !range && !instant was run as range query
rangeQuery = true
}
// We never want to run exemplar query for alerting
- exemplarQuery := model.ExemplarQuery
+ exemplarQuery := false
+ if model.Exemplar != nil {
+ exemplarQuery = *model.Exemplar
+ }
if fromAlert {
exemplarQuery = false
}
@@ -110,7 +121,7 @@ func Parse(query backend.DataQuery, timeInterval string, intervalCalculator inte
Start: query.TimeRange.From,
End: query.TimeRange.To,
RefId: query.RefID,
- InstantQuery: model.InstantQuery,
+ InstantQuery: instantQuery,
RangeQuery: rangeQuery,
ExemplarQuery: exemplarQuery,
UtcOffsetSec: model.UtcOffsetSec,
@@ -139,15 +150,18 @@ func (query *Query) TimeRange() TimeRange {
}
}
-func calculatePrometheusInterval(model *QueryModel, timeInterval string, query backend.DataQuery, intervalCalculator intervalv2.Calculator) (time.Duration, error) {
- queryInterval := model.Interval
-
- //If we are using variable for interval/step, we will replace it with calculated interval
+func calculatePrometheusInterval(
+ queryInterval, timeInterval string,
+ intervalMs, intervalFactor int64,
+ query backend.DataQuery,
+ intervalCalculator intervalv2.Calculator,
+) (time.Duration, error) {
+ // If we are using variable for interval/step, we will replace it with calculated interval
if isVariableInterval(queryInterval) {
queryInterval = ""
}
- minInterval, err := intervalv2.GetIntervalFrom(timeInterval, queryInterval, model.IntervalMS, 15*time.Second)
+ minInterval, err := intervalv2.GetIntervalFrom(timeInterval, queryInterval, intervalMs, 15*time.Second)
if err != nil {
return time.Duration(0), err
}
@@ -159,19 +173,23 @@ func calculatePrometheusInterval(model *QueryModel, timeInterval string, query b
adjustedInterval = calculatedInterval.Value
}
- if model.Interval == varRateInterval || model.Interval == varRateIntervalAlt {
+ if queryInterval == varRateInterval || queryInterval == varRateIntervalAlt {
// Rate interval is final and is not affected by resolution
return calculateRateInterval(adjustedInterval, timeInterval, intervalCalculator), nil
} else {
- intervalFactor := model.IntervalFactor
- if intervalFactor == 0 {
- intervalFactor = 1
+ queryIntervalFactor := intervalFactor
+ if queryIntervalFactor == 0 {
+ queryIntervalFactor = 1
}
- return time.Duration(int64(adjustedInterval) * intervalFactor), nil
+ return time.Duration(int64(adjustedInterval) * queryIntervalFactor), nil
}
}
-func calculateRateInterval(interval time.Duration, scrapeInterval string, intervalCalculator intervalv2.Calculator) time.Duration {
+func calculateRateInterval(
+ interval time.Duration,
+ scrapeInterval string,
+ intervalCalculator intervalv2.Calculator,
+) time.Duration {
scrape := scrapeInterval
if scrape == "" {
scrape = "15s"
@@ -186,13 +204,14 @@ func calculateRateInterval(interval time.Duration, scrapeInterval string, interv
return rateInterval
}
-func interpolateVariables(model *QueryModel, interval time.Duration, timeRange time.Duration, intervalCalculator intervalv2.Calculator, timeInterval string) string {
- expr := model.Expr
+func interpolateVariables(expr, queryInterval string, interval time.Duration,
+ timeRange time.Duration,
+ intervalCalculator intervalv2.Calculator, timeInterval string) string {
rangeMs := timeRange.Milliseconds()
rangeSRounded := int64(math.Round(float64(rangeMs) / 1000.0))
var rateInterval time.Duration
- if model.Interval == varRateInterval || model.Interval == varRateIntervalAlt {
+ if queryInterval == varRateInterval || queryInterval == varRateIntervalAlt {
rateInterval = interval
} else {
rateInterval = calculateRateInterval(interval, timeInterval, intervalCalculator)
@@ -219,7 +238,7 @@ func isVariableInterval(interval string) bool {
if interval == varInterval || interval == varIntervalMs || interval == varRateInterval {
return true
}
- //Repetitive code, we should have functionality to unify these
+ // Repetitive code, we should have functionality to unify these
if interval == varIntervalAlt || interval == varIntervalMsAlt || interval == varRateIntervalAlt {
return true
}
diff --git a/pkg/tsdb/prometheus/models/query_test.go b/pkg/tsdb/prometheus/models/query_test.go
index dd30c5f0b24..ed48c1d0cfa 100644
--- a/pkg/tsdb/prometheus/models/query_test.go
+++ b/pkg/tsdb/prometheus/models/query_test.go
@@ -376,6 +376,7 @@ func TestParse(t *testing.T) {
"format": "time_series",
"intervalFactor": 1,
"interval": "$__rate_interval",
+ "intervalMs": 60000,
"refId": "A"
}`, timeRange)
diff --git a/pkg/tsdb/prometheus/querydata/framing_bench_test.go b/pkg/tsdb/prometheus/querydata/framing_bench_test.go
index 7f319ea72da..798b8f5c519 100644
--- a/pkg/tsdb/prometheus/querydata/framing_bench_test.go
+++ b/pkg/tsdb/prometheus/querydata/framing_bench_test.go
@@ -15,6 +15,8 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
+ "github.com/grafana/grafana/pkg/kindsys"
+ "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/tsdb/prometheus/models"
@@ -121,8 +123,10 @@ func createJsonTestData(start int64, step int64, timestampCount int, seriesCount
bytes := []byte(fmt.Sprintf(`{"status":"success","data":{"resultType":"matrix","result":[%v]}}`, strings.Join(allSeries, ",")))
qm := models.QueryModel{
- RangeQuery: true,
- Expr: "test",
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: kindsys.Ptr(true),
+ Expr: "test",
+ },
}
data, err := json.Marshal(&qm)
diff --git a/pkg/tsdb/prometheus/querydata/framing_test.go b/pkg/tsdb/prometheus/querydata/framing_test.go
index 09355702fc2..0f84e90f55d 100644
--- a/pkg/tsdb/prometheus/querydata/framing_test.go
+++ b/pkg/tsdb/prometheus/querydata/framing_test.go
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/experimental"
+ "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/tsdb/prometheus/models"
@@ -115,12 +116,14 @@ func loadStoredQuery(fileName string) (*backend.QueryDataRequest, error) {
}
qm := models.QueryModel{
- RangeQuery: sq.RangeQuery,
- ExemplarQuery: sq.ExemplarQuery,
- Expr: sq.Expr,
- Interval: fmt.Sprintf("%ds", sq.Step),
- IntervalMS: sq.Step * 1000,
- LegendFormat: sq.LegendFormat,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: &sq.RangeQuery,
+ Exemplar: &sq.ExemplarQuery,
+ Expr: sq.Expr,
+ },
+ Interval: fmt.Sprintf("%ds", sq.Step),
+ IntervalMs: sq.Step * 1000,
+ LegendFormat: sq.LegendFormat,
}
data, err := json.Marshal(&qm)
diff --git a/pkg/tsdb/prometheus/querydata/request_test.go b/pkg/tsdb/prometheus/querydata/request_test.go
index 942ace816a2..d3f6238098b 100644
--- a/pkg/tsdb/prometheus/querydata/request_test.go
+++ b/pkg/tsdb/prometheus/querydata/request_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "fmt"
"io"
"math"
"net/http"
@@ -13,6 +14,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana-plugin-sdk-go/data"
+ "github.com/grafana/grafana/pkg/tsdb/prometheus/kinds/dataquery"
apiv1 "github.com/prometheus/client_golang/api/prometheus/v1"
p "github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
@@ -20,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/log/logtest"
"github.com/grafana/grafana/pkg/infra/tracing"
+ "github.com/grafana/grafana/pkg/kindsys"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/prometheus/client"
"github.com/grafana/grafana/pkg/tsdb/prometheus/models"
@@ -65,9 +68,11 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
require.NoError(t, err)
qm := models.QueryModel{
- LegendFormat: "legend {{app}}",
- UtcOffsetSec: 0,
- ExemplarQuery: true,
+ LegendFormat: "legend {{app}}",
+ UtcOffsetSec: 0,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Exemplar: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -112,7 +117,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "legend {{app}}",
UtcOffsetSec: 0,
- RangeQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -159,7 +166,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "",
UtcOffsetSec: 0,
- RangeQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -202,7 +211,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "",
UtcOffsetSec: 0,
- RangeQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -243,7 +254,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "",
UtcOffsetSec: 0,
- RangeQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Range: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -278,7 +291,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "legend {{app}}",
UtcOffsetSec: 0,
- InstantQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Instant: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -317,7 +332,9 @@ func TestPrometheus_parseTimeSeriesResponse(t *testing.T) {
qm := models.QueryModel{
LegendFormat: "",
UtcOffsetSec: 0,
- InstantQuery: true,
+ PrometheusDataQuery: dataquery.PrometheusDataQuery{
+ Instant: kindsys.Ptr(true),
+ },
}
b, err := json.Marshal(&qm)
require.NoError(t, err)
@@ -354,20 +371,20 @@ func executeWithHeaders(tctx *testContext, query backend.DataQuery, qr interface
}
promRes, err := toAPIResponse(qr)
+ defer func() {
+ if err := promRes.Body.Close(); err != nil {
+ fmt.Println(fmt.Errorf("response body close error: %v", err))
+ }
+ }()
if err != nil {
return nil, err
}
-
tctx.httpProvider.setResponse(promRes)
res, err := tctx.queryData.Execute(context.Background(), &req)
- errClose := promRes.Body.Close()
if err != nil {
return nil, err
}
- if errClose != nil {
- return nil, errClose
- }
return res.Responses[req.Queries[0].RefID].Frames, nil
}
diff --git a/public/app/plugins/datasource/prometheus/dataquery.cue b/public/app/plugins/datasource/prometheus/dataquery.cue
new file mode 100644
index 00000000000..46858e6c92c
--- /dev/null
+++ b/public/app/plugins/datasource/prometheus/dataquery.cue
@@ -0,0 +1,55 @@
+// Copyright 2023 Grafana Labs
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package grafanaplugin
+
+import (
+ common "github.com/grafana/grafana/packages/grafana-schema/src/common"
+ "github.com/grafana/grafana/pkg/plugins/pfs"
+)
+
+// This file (with its sibling .cue files) implements pfs.GrafanaPlugin
+pfs.GrafanaPlugin
+
+composableKinds: DataQuery: {
+ maturity: "experimental"
+
+ lineage: {
+ seqs: [
+ {
+ schemas: [
+ {
+ common.DataQuery
+
+ // The actual expression/query that will be evaluated by Prometheus
+ expr: string
+ // Returns only the latest value that Prometheus has scraped for the requested time series
+ instant?: bool
+ // Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series
+ range?: bool
+ // Execute an additional query to identify interesting raw samples relevant for the given expr
+ exemplar?: bool
+ // Specifies which editor is being used to prepare the query. It can be "code" or "builder"
+ editorMode?: #QueryEditorMode
+ // Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"
+ format?: #PromQueryFormat
+
+ #QueryEditorMode: "code" | "builder" @cuetsy(kind="enum")
+ #PromQueryFormat: "time_series" | "table" | "heatmap" @cuetsy(kind="type")
+ },
+ ]
+ },
+ ]
+ }
+}
diff --git a/public/app/plugins/datasource/prometheus/dataquery.gen.ts b/public/app/plugins/datasource/prometheus/dataquery.gen.ts
new file mode 100644
index 00000000000..6ab137644ae
--- /dev/null
+++ b/public/app/plugins/datasource/prometheus/dataquery.gen.ts
@@ -0,0 +1,47 @@
+// Code generated - EDITING IS FUTILE. DO NOT EDIT.
+//
+// Generated by:
+// public/app/plugins/gen.go
+// Using jennies:
+// TSTypesJenny
+// PluginTSTypesJenny
+//
+// Run 'make gen-cue' from repository root to regenerate.
+
+import * as common from '@grafana/schema';
+
+export const DataQueryModelVersion = Object.freeze([0, 0]);
+
+export enum QueryEditorMode {
+ Builder = 'builder',
+ Code = 'code',
+}
+
+export type PromQueryFormat = ('time_series' | 'table' | 'heatmap');
+
+export interface Prometheus extends common.DataQuery {
+ /**
+ * Specifies which editor is being used to prepare the query. It can be "code" or "builder"
+ */
+ editorMode?: QueryEditorMode;
+ /**
+ * Execute an additional query to identify interesting raw samples relevant for the given expr
+ */
+ exemplar?: boolean;
+ /**
+ * The actual expression/query that will be evaluated by Prometheus
+ */
+ expr: string;
+ /**
+ * Query format to determine how to display data points in panel. It can be "time_series", "table", "heatmap"
+ */
+ format?: PromQueryFormat;
+ /**
+ * Returns only the latest value that Prometheus has scraped for the requested time series
+ */
+ instant?: boolean;
+ /**
+ * Returns a Range vector, comprised of a set of time series containing a range of data points over time for each time series
+ */
+ range?: boolean;
+}
diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts
index 9cced6e00e7..91a75a413e8 100644
--- a/public/app/plugins/datasource/prometheus/datasource.test.ts
+++ b/public/app/plugins/datasource/prometheus/datasource.test.ts
@@ -190,7 +190,7 @@ describe('PrometheusDatasource', () => {
});
describe('customQueryParams', () => {
- const target = { expr: 'test{job="testjob"}', format: 'time_series', refId: '' };
+ const target: PromQuery = { expr: 'test{job="testjob"}', format: 'time_series', refId: '' };
function makeQuery(target: PromQuery) {
return {
@@ -618,7 +618,7 @@ describe('PrometheusDatasource', () => {
describe('interpolateVariablesInQueries', () => {
it('should call replace function 2 times', () => {
- const query = {
+ const query: PromQuery = {
expr: 'test{job="testjob"}',
format: 'time_series',
interval: '$Interval',
diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx
index a258a3b65d6..7f12cb2746b 100644
--- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx
+++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx
@@ -5,6 +5,7 @@ import { EditorField, EditorRow, EditorSwitch } from '@grafana/experimental';
import { AutoSizeInput, RadioButtonGroup, Select } from '@grafana/ui';
import { getQueryTypeChangeHandler, getQueryTypeOptions } from '../../components/PromExploreExtraField';
+import { PromQueryFormat } from '../../dataquery.gen';
import { PromQuery } from '../../types';
import { QueryOptionGroup } from '../shared/QueryOptionGroup';
@@ -28,7 +29,7 @@ export interface Props {
}
export const PromQueryBuilderOptions = React.memo(({ query, app, onChange, onRunQuery }) => {
- const onChangeFormat = (value: SelectableValue) => {
+ const onChangeFormat = (value: SelectableValue) => {
onChange({ ...query, format: value.value });
onRunQuery();
};
diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
index 1057c9ebcd4..524d1e03f10 100644
--- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
+++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx
@@ -8,6 +8,7 @@ import { reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal } from '@grafana/ui';
import { PromQueryEditorProps } from '../../components/types';
+import { PromQueryFormat } from '../../dataquery.gen';
import { PromQuery } from '../../types';
import { QueryPatternsModal } from '../QueryPatternsModal';
import { buildVisualQueryFromString } from '../parsing';
@@ -21,7 +22,7 @@ import { PromQueryBuilderContainer } from './PromQueryBuilderContainer';
import { PromQueryBuilderOptions } from './PromQueryBuilderOptions';
import { PromQueryCodeEditor } from './PromQueryCodeEditor';
-export const FORMAT_OPTIONS: Array> = [
+export const FORMAT_OPTIONS: Array> = [
{ label: 'Time series', value: 'time_series' },
{ label: 'Table', value: 'table' },
{ label: 'Heatmap', value: 'heatmap' },
diff --git a/public/app/plugins/datasource/prometheus/types.ts b/public/app/plugins/datasource/prometheus/types.ts
index 6c324f00233..8f91e893745 100644
--- a/public/app/plugins/datasource/prometheus/types.ts
+++ b/public/app/plugins/datasource/prometheus/types.ts
@@ -1,27 +1,24 @@
-import { DataQuery, DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data';
+import { DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data';
+import { DataQuery } from '@grafana/schema';
import { PromApplication } from '../../../types/unified-alerting-dto';
+import { Prometheus as GenPromQuery } from './dataquery.gen';
import { QueryEditorMode } from './querybuilder/shared/types';
-export interface PromQuery extends DataQuery {
- expr: string;
- format?: string;
- instant?: boolean;
- range?: boolean;
- exemplar?: boolean;
- hinting?: boolean;
- interval?: string;
- intervalFactor?: number;
- // Timezone offset to align start & end time on backend
+export interface PromQuery extends GenPromQuery, DataQuery {
+ /**
+ * Timezone offset to align start & end time on backend
+ */
utcOffsetSec?: number;
legendFormat?: string;
valueWithRefId?: boolean;
requestId?: string;
showingGraph?: boolean;
showingTable?: boolean;
- /** Code, Builder or Explain */
- editorMode?: QueryEditorMode;
+ hinting?: boolean;
+ interval?: string;
+ intervalFactor?: number;
}
export interface PromOptions extends DataSourceJsonData {