diff --git a/pkg/tsdb/loki/api.go b/pkg/tsdb/loki/api.go index a8835da56af..e18752383d2 100644 --- a/pkg/tsdb/loki/api.go +++ b/pkg/tsdb/loki/api.go @@ -85,8 +85,11 @@ func makeDataRequest(ctx context.Context, lokiDsUrl string, query lokiQuery) (*h return nil, err } - if query.VolumeQuery { - req.Header.Set("X-Query-Tags", "Source=logvolhist") + if query.SupportingQueryType != SupportingQueryNone { + value := getSupportingQueryHeaderValue(req, query.SupportingQueryType) + if value != "" { + req.Header.Set("X-Query-Tags", "Source="+value) + } } return req, nil @@ -223,3 +226,18 @@ func (api *LokiAPI) RawQuery(ctx context.Context, resourcePath string) (RawLokiR return encodedBytes, nil } + +func getSupportingQueryHeaderValue(req *http.Request, supportingQueryType SupportingQueryType) string { + value := "" + switch supportingQueryType { + case SupportingQueryLogsVolume: + value = "logvolhist" + case SupportingQueryLogsSample: + value = "logsample" + case SupportingQueryDataSample: + value = "datasample" + default: //ignore + } + + return value +} diff --git a/pkg/tsdb/loki/api_test.go b/pkg/tsdb/loki/api_test.go index 2b64e383bf4..b28d159d895 100644 --- a/pkg/tsdb/loki/api_test.go +++ b/pkg/tsdb/loki/api_test.go @@ -28,7 +28,31 @@ func TestApiLogVolume(t *testing.T) { require.Equal(t, "Source=logvolhist", req.Header.Get("X-Query-Tags")) }) - _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", VolumeQuery: true, QueryType: QueryTypeRange}) + _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryLogsVolume, QueryType: QueryTypeRange}) + require.NoError(t, err) + require.True(t, called) + }) + + t.Run("logs sample queries should set logs sample http header", func(t *testing.T) { + called := false + api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { + called = true + require.Equal(t, "Source=logsample", req.Header.Get("X-Query-Tags")) + }) + + _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryLogsSample, QueryType: QueryTypeRange}) + require.NoError(t, err) + require.True(t, called) + }) + + t.Run("data sample queries should set data sample http header", func(t *testing.T) { + called := false + api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { + called = true + require.Equal(t, "Source=datasample", req.Header.Get("X-Query-Tags")) + }) + + _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryDataSample, QueryType: QueryTypeRange}) require.NoError(t, err) require.True(t, called) }) @@ -40,7 +64,7 @@ func TestApiLogVolume(t *testing.T) { require.Equal(t, "", req.Header.Get("X-Query-Tags")) }) - _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", VolumeQuery: false, QueryType: QueryTypeRange}) + _, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryNone, QueryType: QueryTypeRange}) require.NoError(t, err) require.True(t, called) }) diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index 6925a91c25b..bb0147318a1 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -57,15 +57,15 @@ 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"` - VolumeQuery bool `json:"volumeQuery"` + 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"` } func parseQueryModel(raw json.RawMessage) (*QueryJSONModel, error) { diff --git a/pkg/tsdb/loki/parse_query.go b/pkg/tsdb/loki/parse_query.go index 80f0c0cbc27..5e4434bfce0 100644 --- a/pkg/tsdb/loki/parse_query.go +++ b/pkg/tsdb/loki/parse_query.go @@ -82,6 +82,21 @@ func parseDirection(jsonValue string) (Direction, error) { } } +func parseSupportingQueryType(jsonValue string) (SupportingQueryType, error) { + switch jsonValue { + case "logsVolume": + return SupportingQueryLogsVolume, nil + case "logsSample": + return SupportingQueryLogsSample, nil + case "dataSample": + return SupportingQueryDataSample, nil + case "": + return SupportingQueryNone, nil + default: + return SupportingQueryNone, fmt.Errorf("invalid supportingQueryType: %s", jsonValue) + } +} + func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) { qs := []*lokiQuery{} for _, query := range queryContext.Queries { @@ -115,17 +130,22 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) { return nil, err } + supportingQueryType, err := parseSupportingQueryType(model.SupportingQueryType) + if err != nil { + return nil, err + } + qs = append(qs, &lokiQuery{ - Expr: expr, - QueryType: queryType, - Direction: direction, - Step: step, - MaxLines: model.MaxLines, - LegendFormat: model.LegendFormat, - Start: start, - End: end, - RefID: query.RefID, - VolumeQuery: model.VolumeQuery, + Expr: expr, + QueryType: queryType, + Direction: direction, + Step: step, + MaxLines: model.MaxLines, + LegendFormat: model.LegendFormat, + Start: start, + End: end, + RefID: query.RefID, + SupportingQueryType: supportingQueryType, }) } diff --git a/pkg/tsdb/loki/types.go b/pkg/tsdb/loki/types.go index 9d5fcead26d..c2f1b130fb5 100644 --- a/pkg/tsdb/loki/types.go +++ b/pkg/tsdb/loki/types.go @@ -3,12 +3,20 @@ package loki import "time" type QueryType string +type SupportingQueryType string const ( QueryTypeRange QueryType = "range" QueryTypeInstant QueryType = "instant" ) +const ( + SupportingQueryLogsVolume SupportingQueryType = "logsVolume" + SupportingQueryLogsSample SupportingQueryType = "logsSample" + SupportingQueryDataSample SupportingQueryType = "dataSample" + SupportingQueryNone SupportingQueryType = "none" +) + type Direction string const ( @@ -17,14 +25,14 @@ const ( ) type lokiQuery struct { - Expr string - QueryType QueryType - Direction Direction - Step time.Duration - MaxLines int - LegendFormat string - Start time.Time - End time.Time - RefID string - VolumeQuery bool + Expr string + QueryType QueryType + Direction Direction + Step time.Duration + MaxLines int + LegendFormat string + Start time.Time + End time.Time + RefID string + SupportingQueryType SupportingQueryType } diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index f24469c5ddb..1b19a7acb6d 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -33,7 +33,7 @@ import { CustomVariableModel } from '../../../features/variables/types'; import { LokiDatasource, REF_ID_DATA_SAMPLES } from './datasource'; import { createLokiDatasource, createMetadataRequest } from './mocks'; import { parseToNodeNamesArray } from './queryUtils'; -import { LokiOptions, LokiQuery, LokiQueryType, LokiVariableQueryType } from './types'; +import { LokiOptions, LokiQuery, LokiQueryType, LokiVariableQueryType, SupportingQueryType } from './types'; import { LokiVariableSupport } from './variables'; jest.mock('@grafana/runtime', () => { @@ -981,7 +981,7 @@ describe('LokiDatasource', () => { instant: false, queryType: 'range', refId: 'log-volume-A', - volumeQuery: true, + supportingQueryType: SupportingQueryType.LogsVolume, }); }); diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index be825cd50a3..0d1ec4e37e6 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -86,6 +86,7 @@ import { LokiQueryType, LokiVariableQuery, LokiVariableQueryType, + SupportingQueryType, } from './types'; import { LokiVariableSupport } from './variables'; @@ -191,7 +192,7 @@ export class LokiDatasource ...normalizedQuery, refId: `${REF_ID_STARTER_LOG_VOLUME}${normalizedQuery.refId}`, instant: false, - volumeQuery: true, + supportingQueryType: SupportingQueryType.LogsVolume, expr: `sum by (level) (count_over_time(${expr}[$__interval]))`, }; diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 1a75e42f2d6..d1339f659dc 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -42,8 +42,8 @@ export interface LokiQuery extends DataQuery { legendFormat?: string; maxLines?: number; resolution?: number; - /** Used in range queries */ - volumeQuery?: boolean; + /** 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 */ @@ -154,6 +154,12 @@ export interface LokiVariableQuery extends DataQuery { stream?: string; } +export enum SupportingQueryType { + LogsVolume = 'logsVolume', + LogsSample = 'logsSample', + DataSample = 'dataSample', +} + export interface ContextFilter { enabled: boolean; label: string;