mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Phlare: Use data query schema (#62112)
* Create cue file and gen ts/go types * Use generated schema in ts/go * Run make den-cue to update report * Manually extend Phlare query * Updates * Add default queryType * Run make gen-cue to Update report.json
This commit is contained in:
parent
30b4205521
commit
f3c5e85559
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
keywords:
|
||||||
|
- grafana
|
||||||
|
- schema
|
||||||
|
title: PhlareDataQuery kind
|
||||||
|
---
|
||||||
|
> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
|
||||||
|
|
||||||
|
# PhlareDataQuery kind
|
||||||
|
|
||||||
|
## Maturity: experimental
|
||||||
|
## Version: 0.0
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Required | Description |
|
||||||
|
|-----------------|----------|----------|-----------------------------------------------------|
|
||||||
|
| `groupBy` | string[] | No | Allows to group the results. |
|
||||||
|
| `labelSelector` | string | No | Specifies the query label selectors. Default: `{}`. |
|
||||||
|
| `profileTypeId` | string | No | Specifies the type of profile to query. |
|
||||||
|
|
||||||
|
|
@ -1105,7 +1105,9 @@
|
|||||||
},
|
},
|
||||||
"phlaredataquery": {
|
"phlaredataquery": {
|
||||||
"category": "composable",
|
"category": "composable",
|
||||||
"codeowners": [],
|
"codeowners": [
|
||||||
|
"grafana/observability-traces-and-profiling"
|
||||||
|
],
|
||||||
"currentVersion": [
|
"currentVersion": [
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
@ -1113,13 +1115,13 @@
|
|||||||
"grafanaMaturityCount": 0,
|
"grafanaMaturityCount": 0,
|
||||||
"lineageIsGroup": false,
|
"lineageIsGroup": false,
|
||||||
"links": {
|
"links": {
|
||||||
"docs": "n/a",
|
"docs": "https://grafana.com/docs/grafana/next/developers/kinds/composable/phlaredataquery/schema-reference",
|
||||||
"go": "n/a",
|
"go": "https://github.com/grafana/grafana/tree/main/pkg/tsdb/phlare/kinds/dataquery/types_dataquery_gen.go",
|
||||||
"schema": "n/a",
|
"schema": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/phlare/dataquery.cue",
|
||||||
"ts": "n/a"
|
"ts": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/phlare/dataquery.gen.ts"
|
||||||
},
|
},
|
||||||
"machineName": "phlaredataquery",
|
"machineName": "phlaredataquery",
|
||||||
"maturity": "planned",
|
"maturity": "experimental",
|
||||||
"name": "PhlareDataQuery",
|
"name": "PhlareDataQuery",
|
||||||
"pluralMachineName": "phlaredataquerys",
|
"pluralMachineName": "phlaredataquerys",
|
||||||
"pluralName": "PhlareDataQuerys",
|
"pluralName": "PhlareDataQuerys",
|
||||||
@ -1909,6 +1911,7 @@
|
|||||||
"librarypanel",
|
"librarypanel",
|
||||||
"newspanelcfg",
|
"newspanelcfg",
|
||||||
"nodegraphpanelcfg",
|
"nodegraphpanelcfg",
|
||||||
|
"phlaredataquery",
|
||||||
"piechartpanelcfg",
|
"piechartpanelcfg",
|
||||||
"statetimelinepanelcfg",
|
"statetimelinepanelcfg",
|
||||||
"statpanelcfg",
|
"statpanelcfg",
|
||||||
@ -1918,7 +1921,7 @@
|
|||||||
"textpanelcfg",
|
"textpanelcfg",
|
||||||
"xychartpanelcfg"
|
"xychartpanelcfg"
|
||||||
],
|
],
|
||||||
"count": 18
|
"count": 19
|
||||||
},
|
},
|
||||||
"mature": {
|
"mature": {
|
||||||
"name": "mature",
|
"name": "mature",
|
||||||
@ -1978,7 +1981,6 @@
|
|||||||
"mysqldatasourcecfg",
|
"mysqldatasourcecfg",
|
||||||
"parcadataquery",
|
"parcadataquery",
|
||||||
"parcadatasourcecfg",
|
"parcadatasourcecfg",
|
||||||
"phlaredataquery",
|
|
||||||
"phlaredatasourcecfg",
|
"phlaredatasourcecfg",
|
||||||
"postgresqldataquery",
|
"postgresqldataquery",
|
||||||
"postgresqldatasourcecfg",
|
"postgresqldatasourcecfg",
|
||||||
@ -1996,7 +1998,7 @@
|
|||||||
"zipkindataquery",
|
"zipkindataquery",
|
||||||
"zipkindatasourcecfg"
|
"zipkindatasourcecfg"
|
||||||
],
|
],
|
||||||
"count": 55
|
"count": 54
|
||||||
},
|
},
|
||||||
"stable": {
|
"stable": {
|
||||||
"name": "stable",
|
"name": "stable",
|
||||||
|
53
pkg/tsdb/phlare/kinds/dataquery/types_dataquery_gen.go
Normal file
53
pkg/tsdb/phlare/kinds/dataquery/types_dataquery_gen.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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 PhlareQueryType.
|
||||||
|
const (
|
||||||
|
PhlareQueryTypeBoth PhlareQueryType = "both"
|
||||||
|
|
||||||
|
PhlareQueryTypeMetrics PhlareQueryType = "metrics"
|
||||||
|
|
||||||
|
PhlareQueryTypeProfile PhlareQueryType = "profile"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PhlareDataQuery defines model for PhlareDataQuery.
|
||||||
|
type PhlareDataQuery 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"`
|
||||||
|
|
||||||
|
// Allows to group the results.
|
||||||
|
GroupBy []string `json:"groupBy"`
|
||||||
|
|
||||||
|
// true if query is disabled (ie should not be returned to the dashboard)
|
||||||
|
Hide *bool `json:"hide,omitempty"`
|
||||||
|
|
||||||
|
// Unique, guid like, string used in explore mode
|
||||||
|
Key *string `json:"key,omitempty"`
|
||||||
|
|
||||||
|
// Specifies the query label selectors.
|
||||||
|
LabelSelector string `json:"labelSelector"`
|
||||||
|
|
||||||
|
// Specifies the type of profile to query.
|
||||||
|
ProfileTypeId string `json:"profileTypeId"`
|
||||||
|
|
||||||
|
// Specify the query flavor
|
||||||
|
// TODO make this required and give it a default
|
||||||
|
QueryType *string `json:"queryType,omitempty"`
|
||||||
|
|
||||||
|
// A - Z
|
||||||
|
RefId string `json:"refId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PhlareQueryType defines model for PhlareQueryType.
|
||||||
|
type PhlareQueryType string
|
@ -13,26 +13,23 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/live"
|
"github.com/grafana/grafana-plugin-sdk-go/live"
|
||||||
|
"github.com/grafana/grafana/pkg/tsdb/phlare/kinds/dataquery"
|
||||||
querierv1 "github.com/grafana/phlare/api/gen/proto/go/querier/v1"
|
querierv1 "github.com/grafana/phlare/api/gen/proto/go/querier/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type queryModel struct {
|
type queryModel struct {
|
||||||
WithStreaming bool
|
WithStreaming bool
|
||||||
ProfileTypeID string `json:"profileTypeId"`
|
dataquery.PhlareDataQuery
|
||||||
LabelSelector string `json:"labelSelector"`
|
|
||||||
GroupBy []string `json:"groupBy"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type dsJsonModel struct {
|
type dsJsonModel struct {
|
||||||
MinStep string `json:"minStep"`
|
MinStep string `json:"minStep"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// These constants need to match the ones in the frontend.
|
|
||||||
const queryTypeProfile = "profile"
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
queryTypeMetrics = "metrics"
|
queryTypeProfile = string(dataquery.PhlareQueryTypeProfile)
|
||||||
queryTypeBoth = "both"
|
queryTypeMetrics = string(dataquery.PhlareQueryTypeMetrics)
|
||||||
|
queryTypeBoth = string(dataquery.PhlareQueryTypeBoth)
|
||||||
)
|
)
|
||||||
|
|
||||||
// query processes single Phlare query transforming the response to data.Frame packaged in DataResponse
|
// query processes single Phlare query transforming the response to data.Frame packaged in DataResponse
|
||||||
@ -63,7 +60,7 @@ func (d *PhlareDatasource) query(ctx context.Context, pCtx backend.PluginContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
req := connect.NewRequest(&querierv1.SelectSeriesRequest{
|
req := connect.NewRequest(&querierv1.SelectSeriesRequest{
|
||||||
ProfileTypeID: qm.ProfileTypeID,
|
ProfileTypeID: qm.ProfileTypeId,
|
||||||
LabelSelector: qm.LabelSelector,
|
LabelSelector: qm.LabelSelector,
|
||||||
Start: query.TimeRange.From.UnixMilli(),
|
Start: query.TimeRange.From.UnixMilli(),
|
||||||
End: query.TimeRange.To.UnixMilli(),
|
End: query.TimeRange.To.UnixMilli(),
|
||||||
@ -79,7 +76,7 @@ func (d *PhlareDatasource) query(ctx context.Context, pCtx backend.PluginContext
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
// add the frames to the response.
|
// add the frames to the response.
|
||||||
response.Frames = append(response.Frames, seriesToDataFrames(seriesResp, qm.ProfileTypeID)...)
|
response.Frames = append(response.Frames, seriesToDataFrames(seriesResp, qm.ProfileTypeId)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.QueryType == queryTypeProfile || query.QueryType == queryTypeBoth {
|
if query.QueryType == queryTypeProfile || query.QueryType == queryTypeBoth {
|
||||||
@ -91,7 +88,7 @@ func (d *PhlareDatasource) query(ctx context.Context, pCtx backend.PluginContext
|
|||||||
response.Error = err
|
response.Error = err
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
frame := responseToDataFrames(resp, qm.ProfileTypeID)
|
frame := responseToDataFrames(resp, qm.ProfileTypeId)
|
||||||
response.Frames = append(response.Frames, frame)
|
response.Frames = append(response.Frames, frame)
|
||||||
|
|
||||||
// If query called with streaming on then return a channel
|
// If query called with streaming on then return a channel
|
||||||
@ -113,7 +110,7 @@ func (d *PhlareDatasource) query(ctx context.Context, pCtx backend.PluginContext
|
|||||||
func makeRequest(qm queryModel, query backend.DataQuery) *connect.Request[querierv1.SelectMergeStacktracesRequest] {
|
func makeRequest(qm queryModel, query backend.DataQuery) *connect.Request[querierv1.SelectMergeStacktracesRequest] {
|
||||||
return &connect.Request[querierv1.SelectMergeStacktracesRequest]{
|
return &connect.Request[querierv1.SelectMergeStacktracesRequest]{
|
||||||
Msg: &querierv1.SelectMergeStacktracesRequest{
|
Msg: &querierv1.SelectMergeStacktracesRequest{
|
||||||
ProfileTypeID: qm.ProfileTypeID,
|
ProfileTypeID: qm.ProfileTypeId,
|
||||||
LabelSelector: qm.LabelSelector,
|
LabelSelector: qm.LabelSelector,
|
||||||
Start: query.TimeRange.From.UnixMilli(),
|
Start: query.TimeRange.From.UnixMilli(),
|
||||||
End: query.TimeRange.To.UnixMilli(),
|
End: query.TimeRange.To.UnixMilli(),
|
||||||
|
@ -5,8 +5,9 @@ import { useAsync } from 'react-use';
|
|||||||
import { CoreApp, QueryEditorProps } from '@grafana/data';
|
import { CoreApp, QueryEditorProps } from '@grafana/data';
|
||||||
import { ButtonCascader, CascaderOption } from '@grafana/ui';
|
import { ButtonCascader, CascaderOption } from '@grafana/ui';
|
||||||
|
|
||||||
|
import { defaultPhlare, defaultPhlareQueryType, Phlare } from '../dataquery.gen';
|
||||||
import { PhlareDataSource } from '../datasource';
|
import { PhlareDataSource } from '../datasource';
|
||||||
import { defaultQuery, PhlareDataSourceOptions, ProfileTypeMessage, Query } from '../types';
|
import { PhlareDataSourceOptions, ProfileTypeMessage, Query } from '../types';
|
||||||
|
|
||||||
import { EditorRow } from './EditorRow';
|
import { EditorRow } from './EditorRow';
|
||||||
import { EditorRows } from './EditorRows';
|
import { EditorRows } from './EditorRows';
|
||||||
@ -15,6 +16,11 @@ import { QueryOptions } from './QueryOptions';
|
|||||||
|
|
||||||
export type Props = QueryEditorProps<PhlareDataSource, Query, PhlareDataSourceOptions>;
|
export type Props = QueryEditorProps<PhlareDataSource, Query, PhlareDataSourceOptions>;
|
||||||
|
|
||||||
|
export const defaultQuery: Partial<Phlare> = {
|
||||||
|
...defaultPhlare,
|
||||||
|
queryType: defaultPhlareQueryType,
|
||||||
|
};
|
||||||
|
|
||||||
export function QueryEditor(props: Props) {
|
export function QueryEditor(props: Props) {
|
||||||
const profileTypes = useProfileTypes(props.datasource);
|
const profileTypes = useProfileTypes(props.datasource);
|
||||||
|
|
||||||
|
48
public/app/plugins/datasource/phlare/dataquery.cue
Normal file
48
public/app/plugins/datasource/phlare/dataquery.cue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// 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: [
|
||||||
|
// v0.0
|
||||||
|
{
|
||||||
|
common.DataQuery
|
||||||
|
|
||||||
|
// Specifies the query label selectors.
|
||||||
|
labelSelector: string | *"{}"
|
||||||
|
// Specifies the type of profile to query.
|
||||||
|
profileTypeId: string
|
||||||
|
// Allows to group the results.
|
||||||
|
groupBy: [...string]
|
||||||
|
#PhlareQueryType: "metrics" | "profile" | *"both" @cuetsy(kind="type")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
37
public/app/plugins/datasource/phlare/dataquery.gen.ts
Normal file
37
public/app/plugins/datasource/phlare/dataquery.gen.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// 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 type PhlareQueryType = ('metrics' | 'profile' | 'both');
|
||||||
|
|
||||||
|
export const defaultPhlareQueryType: PhlareQueryType = 'both';
|
||||||
|
|
||||||
|
export interface Phlare extends common.DataQuery {
|
||||||
|
/**
|
||||||
|
* Allows to group the results.
|
||||||
|
*/
|
||||||
|
groupBy: Array<string>;
|
||||||
|
/**
|
||||||
|
* Specifies the query label selectors.
|
||||||
|
*/
|
||||||
|
labelSelector: string;
|
||||||
|
/**
|
||||||
|
* Specifies the type of profile to query.
|
||||||
|
*/
|
||||||
|
profileTypeId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultPhlare: Partial<Phlare> = {
|
||||||
|
groupBy: [],
|
||||||
|
labelSelector: '{}',
|
||||||
|
};
|
@ -1,10 +1,9 @@
|
|||||||
import { DataQuery, DataSourceJsonData } from '@grafana/data';
|
import { DataSourceJsonData } from '@grafana/data';
|
||||||
|
|
||||||
export interface Query extends DataQuery {
|
import { Phlare as PhlareBase, PhlareQueryType } from './dataquery.gen';
|
||||||
labelSelector: string;
|
|
||||||
profileTypeId: string;
|
export interface Query extends PhlareBase {
|
||||||
queryType: 'metrics' | 'profile' | 'both';
|
queryType: PhlareQueryType;
|
||||||
groupBy: string[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProfileTypeMessage {
|
export interface ProfileTypeMessage {
|
||||||
@ -18,12 +17,6 @@ export interface ProfileTypeMessage {
|
|||||||
|
|
||||||
export type SeriesMessage = Array<{ labels: Array<{ name: string; value: string }> }>;
|
export type SeriesMessage = Array<{ labels: Array<{ name: string; value: string }> }>;
|
||||||
|
|
||||||
export const defaultQuery: Partial<Query> = {
|
|
||||||
labelSelector: '{}',
|
|
||||||
queryType: 'both',
|
|
||||||
groupBy: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are options configured for each DataSource instance.
|
* These are options configured for each DataSource instance.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user