diff --git a/docs/sources/developers/kinds/composable/tempodataquery/schema-reference.md b/docs/sources/developers/kinds/composable/tempodataquery/schema-reference.md new file mode 100644 index 000000000000..d8c4229d1288 --- /dev/null +++ b/docs/sources/developers/kinds/composable/tempodataquery/schema-reference.md @@ -0,0 +1,27 @@ +--- +keywords: + - grafana + - schema +title: TempoDataQuery kind +--- +> Both documentation generation and kinds schemas are in active development and subject to change without prior notice. + +# TempoDataQuery kind + +## Maturity: experimental +## Version: 0.0 + +## Properties + +| Property | Type | Required | Description | +|-------------------|---------|----------|----------------------------------------------------------------------------------------------------------------------| +| `limit` | integer | No | Defines the maximum number of traces that are returned from Tempo | +| `maxDuration` | string | No | Define the maximum duration to select traces. Use duration format, for example: 1.2s, 100ms | +| `minDuration` | string | No | Define the minimum duration to select traces. Use duration format, for example: 1.2s, 100ms | +| `query` | string | No | TraceQL query or trace ID | +| `search` | string | No | Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true | +| `serviceMapQuery` | string | No | Filters to be included in a PromQL query to select data for the service graph. Example: {client="app",service="app"} | +| `serviceName` | string | No | Query traces by service name | +| `spanName` | string | No | Query traces by span name | + + diff --git a/pkg/kindsys/report.json b/pkg/kindsys/report.json index 0944a34047fb..af9a9e66874f 100644 --- a/pkg/kindsys/report.json +++ b/pkg/kindsys/report.json @@ -1525,7 +1525,9 @@ }, "tempodataquery": { "category": "composable", - "codeowners": [], + "codeowners": [ + "grafana/observability-traces-and-profiling" + ], "currentVersion": [ 0, 0 @@ -1533,13 +1535,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/tempodataquery/schema-reference", + "go": "https://github.com/grafana/grafana/tree/main/pkg/tsdb/tempo/kinds/dataquery/types_dataquery_gen.go", + "schema": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/tempo/dataquery.cue", + "ts": "https://github.com/grafana/grafana/tree/main/public/app/plugins/datasource/tempo/dataquery.gen.ts" }, "machineName": "tempodataquery", - "maturity": "planned", + "maturity": "experimental", "name": "TempoDataQuery", "pluralMachineName": "tempodataquerys", "pluralName": "TempoDataQuerys", @@ -1904,11 +1906,12 @@ "statetimelinepanelcfg", "statpanelcfg", "statushistorypanelcfg", + "tempodataquery", "testdatadataquery", "textpanelcfg", "xychartpanelcfg" ], - "count": 17 + "count": 18 }, "mature": { "name": "mature", @@ -1977,7 +1980,6 @@ "query", "queryhistory", "tableoldpanelcfg", - "tempodataquery", "tempodatasourcecfg", "testdatadatasourcecfg", "thumb", @@ -1987,7 +1989,7 @@ "zipkindataquery", "zipkindatasourcecfg" ], - "count": 56 + "count": 55 }, "stable": { "name": "stable", diff --git a/pkg/tsdb/tempo/kinds/dataquery/types_dataquery_gen.go b/pkg/tsdb/tempo/kinds/dataquery/types_dataquery_gen.go new file mode 100644 index 000000000000..e78618bda21b --- /dev/null +++ b/pkg/tsdb/tempo/kinds/dataquery/types_dataquery_gen.go @@ -0,0 +1,74 @@ +// 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 TempoQueryType. +const ( + TempoQueryTypeClear TempoQueryType = "clear" + + TempoQueryTypeNativeSearch TempoQueryType = "nativeSearch" + + TempoQueryTypeSearch TempoQueryType = "search" + + TempoQueryTypeServiceMap TempoQueryType = "serviceMap" + + TempoQueryTypeTraceql TempoQueryType = "traceql" + + TempoQueryTypeUpload TempoQueryType = "upload" +) + +// TempoDataQuery defines model for TempoDataQuery. +type TempoDataQuery 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"` + + // 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"` + + // Defines the maximum number of traces that are returned from Tempo + Limit *int64 `json:"limit,omitempty"` + + // Define the maximum duration to select traces. Use duration format, for example: 1.2s, 100ms + MaxDuration *string `json:"maxDuration,omitempty"` + + // Define the minimum duration to select traces. Use duration format, for example: 1.2s, 100ms + MinDuration *string `json:"minDuration,omitempty"` + + // TraceQL query or trace ID + Query string `json:"query"` + + // Specify the query flavor + // TODO make this required and give it a default + QueryType *string `json:"queryType,omitempty"` + + // A - Z + RefId string `json:"refId"` + + // Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true + Search *string `json:"search,omitempty"` + + // Filters to be included in a PromQL query to select data for the service graph. Example: {client="app",service="app"} + ServiceMapQuery *string `json:"serviceMapQuery,omitempty"` + + // Query traces by service name + ServiceName *string `json:"serviceName,omitempty"` + + // Query traces by span name + SpanName *string `json:"spanName,omitempty"` +} + +// search = Loki search, nativeSearch = Tempo search for backwards compatibility +type TempoQueryType string diff --git a/pkg/tsdb/tempo/tempo.go b/pkg/tsdb/tempo/tempo.go index fe8984cbec8e..f52ec3b2c44f 100644 --- a/pkg/tsdb/tempo/tempo.go +++ b/pkg/tsdb/tempo/tempo.go @@ -7,6 +7,8 @@ import ( "io" "net/http" + "github.com/grafana/grafana/pkg/tsdb/tempo/kinds/dataquery" + "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" @@ -34,10 +36,6 @@ type datasourceInfo struct { URL string } -type QueryModel struct { - TraceID string `json:"query"` -} - func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc { return func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { opts, err := settings.HTTPClientOptions() @@ -63,7 +61,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) queryRes := backend.DataResponse{} refID := req.Queries[0].RefID - model := &QueryModel{} + model := &dataquery.TempoDataQuery{} err := json.Unmarshal(req.Queries[0].JSON, model) if err != nil { return result, err @@ -74,7 +72,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) return nil, err } - request, err := s.createRequest(ctx, dsInfo, model.TraceID, req.Queries[0].TimeRange.From.Unix(), req.Queries[0].TimeRange.To.Unix()) + request, err := s.createRequest(ctx, dsInfo, model.Query, req.Queries[0].TimeRange.From.Unix(), req.Queries[0].TimeRange.To.Unix()) if err != nil { return result, err } @@ -96,7 +94,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) } if resp.StatusCode != http.StatusOK { - queryRes.Error = fmt.Errorf("failed to get trace with id: %s Status: %s Body: %s", model.TraceID, resp.Status, string(body)) + queryRes.Error = fmt.Errorf("failed to get trace with id: %s Status: %s Body: %s", model.Query, resp.Status, string(body)) result.Responses[refID] = queryRes return result, nil } @@ -109,7 +107,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) frame, err := TraceToFrame(otTrace) if err != nil { - return &backend.QueryDataResponse{}, fmt.Errorf("failed to transform trace %v to data frame: %w", model.TraceID, err) + return &backend.QueryDataResponse{}, fmt.Errorf("failed to transform trace %v to data frame: %w", model.Query, err) } frame.RefID = refID frames := []*data.Frame{frame} diff --git a/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx b/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx index 5597d05e5a59..e8dc49370ce4 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx @@ -17,9 +17,10 @@ import { import { LokiQueryField } from '../../loki/components/LokiQueryField'; import { LokiDatasource } from '../../loki/datasource'; import { LokiQuery } from '../../loki/types'; +import { TempoQueryType } from '../dataquery.gen'; import { TempoDatasource } from '../datasource'; import { QueryEditor } from '../traceql/QueryEditor'; -import { TempoQuery, TempoQueryType } from '../types'; +import { TempoQuery } from '../types'; import NativeSearch from './NativeSearch'; import { ServiceGraphSection } from './ServiceGraphSection'; diff --git a/public/app/plugins/datasource/tempo/dataquery.cue b/public/app/plugins/datasource/tempo/dataquery.cue new file mode 100644 index 000000000000..3a45934c6002 --- /dev/null +++ b/public/app/plugins/datasource/tempo/dataquery.cue @@ -0,0 +1,59 @@ +// 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 + + // TraceQL query or trace ID + query: string + // Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true + search?: string + // Query traces by service name + serviceName?: string + // Query traces by span name + spanName?: string + // Define the minimum duration to select traces. Use duration format, for example: 1.2s, 100ms + minDuration?: string + // Define the maximum duration to select traces. Use duration format, for example: 1.2s, 100ms + maxDuration?: string + // Filters to be included in a PromQL query to select data for the service graph. Example: {client="app",service="app"} + serviceMapQuery?: string + // Defines the maximum number of traces that are returned from Tempo + limit?: int64 + + // search = Loki search, nativeSearch = Tempo search for backwards compatibility + #TempoQueryType: "traceql" | "search" | "serviceMap" | "upload" | "nativeSearch" | "clear" @cuetsy(kind="type") + }, + ] + }, + ] + } +} diff --git a/public/app/plugins/datasource/tempo/dataquery.gen.ts b/public/app/plugins/datasource/tempo/dataquery.gen.ts new file mode 100644 index 000000000000..e53d7f896cc8 --- /dev/null +++ b/public/app/plugins/datasource/tempo/dataquery.gen.ts @@ -0,0 +1,53 @@ +// 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]); + +/** + * search = Loki search, nativeSearch = Tempo search for backwards compatibility + */ +export type TempoQueryType = ('traceql' | 'search' | 'serviceMap' | 'upload' | 'nativeSearch' | 'clear'); + +export interface Tempo extends common.DataQuery { + /** + * Defines the maximum number of traces that are returned from Tempo + */ + limit?: number; + /** + * Define the maximum duration to select traces. Use duration format, for example: 1.2s, 100ms + */ + maxDuration?: string; + /** + * Define the minimum duration to select traces. Use duration format, for example: 1.2s, 100ms + */ + minDuration?: string; + /** + * TraceQL query or trace ID + */ + query: string; + /** + * Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true + */ + search?: string; + /** + * Filters to be included in a PromQL query to select data for the service graph. Example: {client="app",service="app"} + */ + serviceMapQuery?: string; + /** + * Query traces by service name + */ + serviceName?: string; + /** + * Query traces by span name + */ + spanName?: string; +} diff --git a/public/app/plugins/datasource/tempo/types.ts b/public/app/plugins/datasource/tempo/types.ts index 1afea44df28f..cab23f627c92 100644 --- a/public/app/plugins/datasource/tempo/types.ts +++ b/public/app/plugins/datasource/tempo/types.ts @@ -1,10 +1,11 @@ -import { DataQuery } from '@grafana/data'; import { DataSourceJsonData, KeyValue } from '@grafana/data/src'; import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import { LokiQuery } from '../loki/types'; +import { Tempo as TempoBase, TempoQueryType } from './dataquery.gen'; + export interface SearchQueryParams { minDuration?: string; maxDuration?: string; @@ -36,21 +37,11 @@ export interface TempoJsonData extends DataSourceJsonData { }; } -// search = Loki search, nativeSearch = Tempo search for backwards compatibility -export type TempoQueryType = 'traceql' | 'search' | 'serviceMap' | 'upload' | 'nativeSearch' | 'clear'; - -export interface TempoQuery extends DataQuery { - query: string; +export interface TempoQuery extends TempoBase { // Query to find list of traces, e.g., via Loki + // TODO change this field to the schema type when LokiQuery exists in the schema linkedQuery?: LokiQuery; - search?: string; queryType: TempoQueryType; - serviceName?: string; - spanName?: string; - minDuration?: string; - maxDuration?: string; - limit?: number; - serviceMapQuery?: string; } export interface MyDataSourceOptions extends DataSourceJsonData {}