mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Loki: Add X-Query-Tags header for logs sample and data sample (#62333)
This commit is contained in:
parent
9453bec819
commit
d0e95f8c95
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -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]))`,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user