diff --git a/docs/sources/developers/kinds/composable/lokidataquery/schema-reference.md b/docs/sources/developers/kinds/composable/lokidataquery/schema-reference.md
new file mode 100644
index 00000000000..0953661df24
--- /dev/null
+++ b/docs/sources/developers/kinds/composable/lokidataquery/schema-reference.md
@@ -0,0 +1,47 @@
+---
+keywords:
+ - grafana
+ - schema
+title: LokiDataQuery kind
+---
+> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
+
+## LokiDataQuery
+
+#### Maturity: experimental
+#### Version: 0.0
+
+
+
+It extends [DataQuery](#dataquery).
+
+| Property | Type | Required | Description |
+|----------------|---------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `expr` | string | **Yes** | The LogQL query. |
+| `refId` | string | **Yes** | *(Inherited from [DataQuery](#dataquery))*
A - Z |
+| `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`. |
+| `hide` | boolean | No | *(Inherited from [DataQuery](#dataquery))*
true if query is disabled (ie should not be returned to the dashboard) |
+| `instant` | boolean | No | @deprecated, now use queryType. |
+| `key` | string | No | *(Inherited from [DataQuery](#dataquery))*
Unique, guid like, string used in explore mode |
+| `legendFormat` | string | No | Used to override the name of the series. |
+| `maxLines` | integer | No | Used to limit the number of log rows returned. |
+| `queryType` | string | No | *(Inherited from [DataQuery](#dataquery))*
Specify the query flavor
TODO make this required and give it a default |
+| `range` | boolean | No | @deprecated, now use queryType. |
+| `resolution` | integer | No | Used to scale the interval value. |
+
+### 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 - Z |
+| `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) |
+| `key` | string | No | Unique, guid like, string used in explore mode |
+| `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 1e3fe9c0ddb..0b3ca46a0b6 100644
--- a/pkg/kindsys/report.json
+++ b/pkg/kindsys/report.json
@@ -908,7 +908,9 @@
},
"lokidataquery": {
"category": "composable",
- "codeowners": [],
+ "codeowners": [
+ "grafana/observability-logs"
+ ],
"currentVersion": [
0,
0
@@ -916,13 +918,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/lokidataquery/schema-reference",
+ "go": "https://github.com/grafana/grafana/tree/main/pkg/tsdb/loki/kinds/dataquery/types_dataquery_gen.go",
+ "schema": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/loki/dataquery.cue",
+ "ts": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/loki/dataquery.gen.ts"
},
"machineName": "lokidataquery",
- "maturity": "planned",
+ "maturity": "experimental",
"name": "LokiDataQuery",
"pluralMachineName": "lokidataquerys",
"pluralName": "LokiDataQuerys",
@@ -1981,6 +1983,7 @@
"gaugepanelcfg",
"histogrampanelcfg",
"librarypanel",
+ "lokidataquery",
"newspanelcfg",
"nodegraphpanelcfg",
"phlaredataquery",
@@ -1993,7 +1996,7 @@
"textpanelcfg",
"xychartpanelcfg"
],
- "count": 19
+ "count": 20
},
"mature": {
"name": "mature",
@@ -2045,7 +2048,6 @@
"jaegerdatasourcecfg",
"livepanelcfg",
"logspanelcfg",
- "lokidataquery",
"lokidatasourcecfg",
"microsoftsqlserverdataquery",
"microsoftsqlserverdatasourcecfg",
@@ -2070,7 +2072,7 @@
"zipkindataquery",
"zipkindatasourcecfg"
],
- "count": 53
+ "count": 52
},
"stable": {
"name": "stable",
diff --git a/pkg/tsdb/loki/kinds/dataquery/types_dataquery_gen.go b/pkg/tsdb/loki/kinds/dataquery/types_dataquery_gen.go
new file mode 100644
index 00000000000..02706b278e7
--- /dev/null
+++ b/pkg/tsdb/loki/kinds/dataquery/types_dataquery_gen.go
@@ -0,0 +1,105 @@
+// 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 EditorMode.
+const (
+ EditorModeBuilder EditorMode = "builder"
+
+ EditorModeCode EditorMode = "code"
+)
+
+// Defines values for LokiQueryDirection.
+const (
+ LokiQueryDirectionBackward LokiQueryDirection = "backward"
+
+ LokiQueryDirectionForward LokiQueryDirection = "forward"
+)
+
+// Defines values for LokiQueryType.
+const (
+ LokiQueryTypeInstant LokiQueryType = "instant"
+
+ LokiQueryTypeRange LokiQueryType = "range"
+
+ LokiQueryTypeStream LokiQueryType = "stream"
+)
+
+// Defines values for QueryEditorMode.
+const (
+ QueryEditorModeBuilder QueryEditorMode = "builder"
+
+ QueryEditorModeCode QueryEditorMode = "code"
+)
+
+// Defines values for SupportingQueryType.
+const (
+ SupportingQueryTypeDataSample SupportingQueryType = "dataSample"
+
+ SupportingQueryTypeLogsSample SupportingQueryType = "logsSample"
+
+ SupportingQueryTypeLogsVolume SupportingQueryType = "logsVolume"
+)
+
+// LokiDataQuery defines model for LokiDataQuery.
+type LokiDataQuery 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"`
+ EditorMode *EditorMode `json:"editorMode,omitempty"`
+
+ // The LogQL query.
+ Expr string `json:"expr"`
+
+ // true if query is disabled (ie should not be returned to the dashboard)
+ Hide *bool `json:"hide,omitempty"`
+
+ // @deprecated, now use queryType.
+ Instant *bool `json:"instant,omitempty"`
+
+ // Unique, guid like, string used in explore mode
+ Key *string `json:"key,omitempty"`
+
+ // Used to override the name of the series.
+ LegendFormat *string `json:"legendFormat,omitempty"`
+
+ // Used to limit the number of log rows returned.
+ MaxLines *int64 `json:"maxLines,omitempty"`
+
+ // Specify the query flavor
+ // TODO make this required and give it a default
+ QueryType *string `json:"queryType,omitempty"`
+
+ // @deprecated, now use queryType.
+ Range *bool `json:"range,omitempty"`
+
+ // A - Z
+ RefId string `json:"refId"`
+
+ // Used to scale the interval value.
+ Resolution *int64 `json:"resolution,omitempty"`
+}
+
+// EditorMode defines model for LokiDataQuery.EditorMode.
+type EditorMode string
+
+// LokiQueryDirection defines model for LokiQueryDirection.
+type LokiQueryDirection string
+
+// LokiQueryType defines model for LokiQueryType.
+type LokiQueryType string
+
+// QueryEditorMode defines model for QueryEditorMode.
+type QueryEditorMode string
+
+// SupportingQueryType defines model for SupportingQueryType.
+type SupportingQueryType string
diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go
index 06c57a90924..ced18ad9fd4 100644
--- a/pkg/tsdb/loki/loki.go
+++ b/pkg/tsdb/loki/loki.go
@@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
+ "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery"
)
var logger = log.New("tsdb.loki")
@@ -57,15 +58,9 @@ type datasourceInfo struct {
}
type QueryJSONModel struct {
- QueryType string `json:"queryType"`
- Expr string `json:"expr"`
- Direction string `json:"direction"`
- LegendFormat string `json:"legendFormat"`
- Interval string `json:"interval"`
- IntervalMS int `json:"intervalMS"`
- Resolution int64 `json:"resolution"`
- MaxLines int `json:"maxLines"`
- SupportingQueryType string `json:"supportingQueryType"`
+ dataquery.LokiDataQuery
+ Direction *string `json:"direction,omitempty"`
+ SupportingQueryType *string `json:"supportingQueryType"`
}
func parseQueryModel(raw json.RawMessage) (*QueryJSONModel, error) {
diff --git a/pkg/tsdb/loki/parse_query.go b/pkg/tsdb/loki/parse_query.go
index b4b1f889088..f510f0c43bb 100644
--- a/pkg/tsdb/loki/parse_query.go
+++ b/pkg/tsdb/loki/parse_query.go
@@ -53,48 +53,57 @@ func interpolateVariables(expr string, interval time.Duration, timeRange time.Du
return expr
}
-func parseQueryType(jsonValue string) (QueryType, error) {
- switch jsonValue {
- case "instant":
- return QueryTypeInstant, nil
- case "range":
- return QueryTypeRange, nil
- case "":
+func parseQueryType(jsonPointerValue *string) (QueryType, error) {
+ if jsonPointerValue == nil {
// there are older queries stored in alerting that did not have queryType,
// those were range-queries
return QueryTypeRange, nil
- default:
- return QueryTypeRange, fmt.Errorf("invalid queryType: %s", jsonValue)
+ } else {
+ jsonValue := *jsonPointerValue
+ switch jsonValue {
+ case "instant":
+ return QueryTypeInstant, nil
+ case "range":
+ return QueryTypeRange, nil
+ default:
+ return QueryTypeRange, fmt.Errorf("invalid queryType: %s", jsonValue)
+ }
}
}
-func parseDirection(jsonValue string) (Direction, error) {
- switch jsonValue {
- case "backward":
- return DirectionBackward, nil
- case "forward":
- return DirectionForward, nil
- case "":
+func parseDirection(jsonPointerValue *string) (Direction, error) {
+ if jsonPointerValue == nil {
// there are older queries stored in alerting that did not have queryDirection,
// we default to "backward"
return DirectionBackward, nil
- default:
- return DirectionBackward, fmt.Errorf("invalid queryDirection: %s", jsonValue)
+ } else {
+ jsonValue := *jsonPointerValue
+ switch jsonValue {
+ case "backward":
+ return DirectionBackward, nil
+ case "forward":
+ return DirectionForward, nil
+ default:
+ return DirectionBackward, fmt.Errorf("invalid queryDirection: %s", jsonValue)
+ }
}
}
-func parseSupportingQueryType(jsonValue string) (SupportingQueryType, error) {
- switch jsonValue {
- case "logsVolume":
- return SupportingQueryLogsVolume, nil
- case "logsSample":
- return SupportingQueryLogsSample, nil
- case "dataSample":
- return SupportingQueryDataSample, nil
- case "":
+func parseSupportingQueryType(jsonPointerValue *string) (SupportingQueryType, error) {
+ if jsonPointerValue == nil {
return SupportingQueryNone, nil
- default:
- return SupportingQueryNone, fmt.Errorf("invalid supportingQueryType: %s", jsonValue)
+ } else {
+ jsonValue := *jsonPointerValue
+ switch jsonValue {
+ case "logsVolume":
+ return SupportingQueryLogsVolume, nil
+ case "logsSample":
+ return SupportingQueryLogsSample, nil
+ case "dataSample":
+ return SupportingQueryDataSample, nil
+ default:
+ return SupportingQueryNone, fmt.Errorf("invalid supportingQueryType: %s", jsonValue)
+ }
}
}
@@ -110,8 +119,8 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
end := query.TimeRange.To
var resolution int64 = 1
- if model.Resolution >= 1 && model.Resolution <= 5 || model.Resolution == 10 {
- resolution = model.Resolution
+ if model.Resolution != nil && (*model.Resolution >= 1 && *model.Resolution <= 5 || *model.Resolution == 10) {
+ resolution = *model.Resolution
}
interval := query.Interval
@@ -131,6 +140,16 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
return nil, err
}
+ var maxLines int64
+ if model.MaxLines != nil {
+ maxLines = *model.MaxLines
+ }
+
+ var legendFormat string
+ if model.LegendFormat != nil {
+ legendFormat = *model.LegendFormat
+ }
+
supportingQueryType, err := parseSupportingQueryType(model.SupportingQueryType)
if err != nil {
return nil, err
@@ -141,8 +160,8 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
QueryType: queryType,
Direction: direction,
Step: step,
- MaxLines: model.MaxLines,
- LegendFormat: model.LegendFormat,
+ MaxLines: int(maxLines),
+ LegendFormat: legendFormat,
Start: start,
End: end,
RefID: query.RefID,
diff --git a/pkg/tsdb/loki/types.go b/pkg/tsdb/loki/types.go
index c2f1b130fb5..06f8b1836b5 100644
--- a/pkg/tsdb/loki/types.go
+++ b/pkg/tsdb/loki/types.go
@@ -1,27 +1,30 @@
package loki
-import "time"
+import (
+ "time"
-type QueryType string
-type SupportingQueryType string
+ "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery"
+)
+
+type QueryType = dataquery.LokiQueryType
+type SupportingQueryType = dataquery.SupportingQueryType
+type Direction = dataquery.LokiQueryDirection
const (
- QueryTypeRange QueryType = "range"
- QueryTypeInstant QueryType = "instant"
+ QueryTypeRange = dataquery.LokiQueryTypeRange
+ QueryTypeInstant = dataquery.LokiQueryTypeInstant
)
const (
- SupportingQueryLogsVolume SupportingQueryType = "logsVolume"
- SupportingQueryLogsSample SupportingQueryType = "logsSample"
- SupportingQueryDataSample SupportingQueryType = "dataSample"
+ SupportingQueryLogsVolume = dataquery.SupportingQueryTypeLogsVolume
+ SupportingQueryLogsSample = dataquery.SupportingQueryTypeLogsSample
+ SupportingQueryDataSample = dataquery.SupportingQueryTypeDataSample
SupportingQueryNone SupportingQueryType = "none"
)
-type Direction string
-
const (
- DirectionBackward Direction = "backward"
- DirectionForward Direction = "forward"
+ DirectionBackward = dataquery.LokiQueryDirectionBackward
+ DirectionForward = dataquery.LokiQueryDirectionForward
)
type lokiQuery struct {
diff --git a/public/app/plugins/datasource/loki/dataquery.cue b/public/app/plugins/datasource/loki/dataquery.cue
new file mode 100644
index 00000000000..c327d4f44e4
--- /dev/null
+++ b/public/app/plugins/datasource/loki/dataquery.cue
@@ -0,0 +1,61 @@
+// 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 (
+ "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 LogQL query.
+ expr: string
+ // Used to override the name of the series.
+ legendFormat?: string
+ // Used to limit the number of log rows returned.
+ maxLines?: int64
+ // Used to scale the interval value.
+ resolution?: int64
+ editorMode?: #QueryEditorMode
+ // @deprecated, now use queryType.
+ range?: bool
+ // @deprecated, now use queryType.
+ instant?: bool
+
+ #QueryEditorMode: "code" | "builder" @cuetsy(kind="enum")
+
+ #LokiQueryType: "range" | "instant" | "stream" @cuetsy(kind="enum")
+
+ #SupportingQueryType: "logsVolume" | "logsSample" | "dataSample" @cuetsy(kind="enum")
+
+ #LokiQueryDirection: "forward" | "backward" @cuetsy(kind="enum")
+ },
+ ]
+ },
+ ]
+ }
+}
diff --git a/public/app/plugins/datasource/loki/dataquery.gen.ts b/public/app/plugins/datasource/loki/dataquery.gen.ts
new file mode 100644
index 00000000000..aab59830ff4
--- /dev/null
+++ b/public/app/plugins/datasource/loki/dataquery.gen.ts
@@ -0,0 +1,63 @@
+// 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 enum LokiQueryType {
+ Instant = 'instant',
+ Range = 'range',
+ Stream = 'stream',
+}
+
+export enum SupportingQueryType {
+ DataSample = 'dataSample',
+ LogsSample = 'logsSample',
+ LogsVolume = 'logsVolume',
+}
+
+export enum LokiQueryDirection {
+ Backward = 'backward',
+ Forward = 'forward',
+}
+
+export interface Loki extends common.DataQuery {
+ editorMode?: QueryEditorMode;
+ /**
+ * The LogQL query.
+ */
+ expr: string;
+ /**
+ * @deprecated, now use queryType.
+ */
+ instant?: boolean;
+ /**
+ * Used to override the name of the series.
+ */
+ legendFormat?: string;
+ /**
+ * Used to limit the number of log rows returned.
+ */
+ maxLines?: number;
+ /**
+ * @deprecated, now use queryType.
+ */
+ range?: boolean;
+ /**
+ * Used to scale the interval value.
+ */
+ resolution?: number;
+}
diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts
index ec4650b12b7..30a1c7160b7 100644
--- a/public/app/plugins/datasource/loki/types.ts
+++ b/public/app/plugins/datasource/loki/types.ts
@@ -1,6 +1,8 @@
import { DataQuery, DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data';
-import { QueryEditorMode } from '../prometheus/querybuilder/shared/types';
+import { Loki as LokiQueryFromSchema, LokiQueryType, SupportingQueryType, LokiQueryDirection } from './dataquery.gen';
+
+export { LokiQueryDirection, LokiQueryType, SupportingQueryType };
export interface LokiInstantQueryRequest {
query: string;
@@ -24,31 +26,15 @@ export enum LokiResultType {
Matrix = 'matrix',
}
-export enum LokiQueryType {
- Range = 'range',
- Instant = 'instant',
- Stream = 'stream',
-}
-
-export enum LokiQueryDirection {
- Backward = 'backward',
- Forward = 'forward',
-}
-
-export interface LokiQuery extends DataQuery {
- queryType?: LokiQueryType;
- expr: string;
+export interface LokiQuery extends LokiQueryFromSchema {
direction?: LokiQueryDirection;
- legendFormat?: string;
- maxLines?: number;
- resolution?: number;
/** Used only to identify supporting queries, e.g. logs volume, logs sample and data sample */
supportingQueryType?: SupportingQueryType;
- /* @deprecated now use queryType */
- range?: boolean;
- /* @deprecated now use queryType */
- instant?: boolean;
- editorMode?: QueryEditorMode;
+ // CUE autogenerates `queryType` as `?string`, as that's how it is defined
+ // in the parent-interface (in DataQuery).
+ // the temporary fix (until this gets improved in the codegen), is to
+ // override it here
+ queryType?: LokiQueryType;
}
export interface LokiOptions extends DataSourceJsonData {
@@ -161,12 +147,6 @@ export interface QueryStats {
entries: number;
}
-export enum SupportingQueryType {
- LogsVolume = 'logsVolume',
- LogsSample = 'logsSample',
- DataSample = 'dataSample',
-}
-
export interface ContextFilter {
enabled: boolean;
label: string;