mirror of
https://github.com/grafana/grafana.git
synced 2025-01-10 08:03:58 -06:00
loki: run some queries through the backend (#44729)
This commit is contained in:
parent
3a2e3267ba
commit
560c773905
@ -29,6 +29,7 @@ export interface FeatureToggles {
|
|||||||
tempoSearch?: boolean;
|
tempoSearch?: boolean;
|
||||||
tempoBackendSearch?: boolean;
|
tempoBackendSearch?: boolean;
|
||||||
tempoServiceGraph?: boolean;
|
tempoServiceGraph?: boolean;
|
||||||
|
lokiBackendMode?: boolean;
|
||||||
fullRangeLogsVolume?: boolean;
|
fullRangeLogsVolume?: boolean;
|
||||||
accesscontrol?: boolean;
|
accesscontrol?: boolean;
|
||||||
prometheus_azure_auth?: boolean;
|
prometheus_azure_auth?: boolean;
|
||||||
|
@ -72,6 +72,12 @@ var (
|
|||||||
State: FeatureStateBeta,
|
State: FeatureStateBeta,
|
||||||
FrontendOnly: true,
|
FrontendOnly: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "lokiBackendMode",
|
||||||
|
Description: "Loki datasource works as backend datasource",
|
||||||
|
State: FeatureStateAlpha,
|
||||||
|
FrontendOnly: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "fullRangeLogsVolume",
|
Name: "fullRangeLogsVolume",
|
||||||
Description: "Show full range logs volume in explore",
|
Description: "Show full range logs volume in explore",
|
||||||
|
@ -55,6 +55,10 @@ const (
|
|||||||
// show service
|
// show service
|
||||||
FlagTempoServiceGraph = "tempoServiceGraph"
|
FlagTempoServiceGraph = "tempoServiceGraph"
|
||||||
|
|
||||||
|
// FlagLokiBackendMode
|
||||||
|
// Loki datasource works as backend datasource
|
||||||
|
FlagLokiBackendMode = "lokiBackendMode"
|
||||||
|
|
||||||
// FlagFullRangeLogsVolume
|
// FlagFullRangeLogsVolume
|
||||||
// Show full range logs volume in explore
|
// Show full range logs volume in explore
|
||||||
FlagFullRangeLogsVolume = "fullRangeLogsVolume"
|
FlagFullRangeLogsVolume = "fullRangeLogsVolume"
|
||||||
|
@ -8,12 +8,12 @@ import Prism from 'prismjs';
|
|||||||
import {
|
import {
|
||||||
AnnotationEvent,
|
AnnotationEvent,
|
||||||
AnnotationQueryRequest,
|
AnnotationQueryRequest,
|
||||||
|
CoreApp,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
DataFrameView,
|
DataFrameView,
|
||||||
DataQueryError,
|
DataQueryError,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
DataQueryResponse,
|
DataQueryResponse,
|
||||||
DataSourceApi,
|
|
||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
DataSourceWithLogsContextSupport,
|
DataSourceWithLogsContextSupport,
|
||||||
DataSourceWithLogsVolumeSupport,
|
DataSourceWithLogsVolumeSupport,
|
||||||
@ -33,7 +33,7 @@ import {
|
|||||||
ScopedVars,
|
ScopedVars,
|
||||||
TimeRange,
|
TimeRange,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { BackendSrvRequest, FetchError, getBackendSrv } from '@grafana/runtime';
|
import { BackendSrvRequest, FetchError, getBackendSrv, DataSourceWithBackend } from '@grafana/runtime';
|
||||||
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { addLabelToQuery } from './add_label_to_query';
|
import { addLabelToQuery } from './add_label_to_query';
|
||||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
@ -44,7 +44,7 @@ import {
|
|||||||
lokiStreamsToDataFrames,
|
lokiStreamsToDataFrames,
|
||||||
processRangeQueryResponse,
|
processRangeQueryResponse,
|
||||||
} from './result_transformer';
|
} from './result_transformer';
|
||||||
import { addParsedLabelToQuery, queryHasPipeParser } from './query_utils';
|
import { addParsedLabelToQuery, getNormalizedLokiQuery, queryHasPipeParser } from './query_utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LokiOptions,
|
LokiOptions,
|
||||||
@ -86,7 +86,7 @@ const DEFAULT_QUERY_PARAMS: Partial<LokiRangeQueryRequest> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class LokiDatasource
|
export class LokiDatasource
|
||||||
extends DataSourceApi<LokiQuery, LokiOptions>
|
extends DataSourceWithBackend<LokiQuery, LokiOptions>
|
||||||
implements
|
implements
|
||||||
DataSourceWithLogsContextSupport,
|
DataSourceWithLogsContextSupport,
|
||||||
DataSourceWithLogsVolumeSupport<LokiQuery>,
|
DataSourceWithLogsVolumeSupport<LokiQuery>,
|
||||||
@ -157,13 +157,37 @@ export class LokiDatasource
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
query(options: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> {
|
query(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> {
|
||||||
const subQueries: Array<Observable<DataQueryResponse>> = [];
|
const subQueries: Array<Observable<DataQueryResponse>> = [];
|
||||||
const scopedVars = {
|
const scopedVars = {
|
||||||
...options.scopedVars,
|
...request.scopedVars,
|
||||||
...this.getRangeScopedVars(options.range),
|
...this.getRangeScopedVars(request.range),
|
||||||
};
|
};
|
||||||
const filteredTargets = options.targets
|
|
||||||
|
// if all these are true, run query through backend:
|
||||||
|
// - feature-flag is enabled
|
||||||
|
// - we are in explore-mode
|
||||||
|
// - for every query it is true that:
|
||||||
|
// - query is range query
|
||||||
|
// - and query is metric query
|
||||||
|
// - and query is not a log-volume-query (those need a custom http header)
|
||||||
|
const shouldRunBackendQuery =
|
||||||
|
config.featureToggles.lokiBackendMode &&
|
||||||
|
request.app === CoreApp.Explore &&
|
||||||
|
request.targets.every(
|
||||||
|
(query) => query.queryType === LokiQueryType.Range && isMetricsQuery(query.expr) && !query.volumeQuery
|
||||||
|
);
|
||||||
|
|
||||||
|
if (shouldRunBackendQuery) {
|
||||||
|
// we "fix" the loki queries to have `.queryType` and not have `.instant` and `.range`
|
||||||
|
const fixedRequest = {
|
||||||
|
...request,
|
||||||
|
targets: request.targets.map(getNormalizedLokiQuery),
|
||||||
|
};
|
||||||
|
return super.query(fixedRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredTargets = request.targets
|
||||||
.filter((target) => target.expr && !target.hide)
|
.filter((target) => target.expr && !target.hide)
|
||||||
.map((target) => {
|
.map((target) => {
|
||||||
const expr = this.addAdHocFilters(target.expr);
|
const expr = this.addAdHocFilters(target.expr);
|
||||||
@ -175,9 +199,9 @@ export class LokiDatasource
|
|||||||
|
|
||||||
for (const target of filteredTargets) {
|
for (const target of filteredTargets) {
|
||||||
if (target.instant || target.queryType === LokiQueryType.Instant) {
|
if (target.instant || target.queryType === LokiQueryType.Instant) {
|
||||||
subQueries.push(this.runInstantQuery(target, options, filteredTargets.length));
|
subQueries.push(this.runInstantQuery(target, request, filteredTargets.length));
|
||||||
} else {
|
} else {
|
||||||
subQueries.push(this.runRangeQuery(target, options, filteredTargets.length));
|
subQueries.push(this.runRangeQuery(target, request, filteredTargets.length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,6 +779,26 @@ export class LokiDatasource
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when running queries through backend
|
||||||
|
filterQuery(query: LokiQuery): boolean {
|
||||||
|
if (query.hide || query.expr === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used when running queries through backend
|
||||||
|
applyTemplateVariables(target: LokiQuery, scopedVars: ScopedVars): Record<string, any> {
|
||||||
|
// We want to interpolate these variables on backend
|
||||||
|
const { __interval, __interval_ms, ...rest } = scopedVars;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...target,
|
||||||
|
legendFormat: this.templateSrv.replace(target.legendFormat, rest),
|
||||||
|
expr: this.templateSrv.replace(target.expr, rest, this.interpolateQueryExpr),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
interpolateString(string: string) {
|
interpolateString(string: string) {
|
||||||
return this.templateSrv.replace(string, undefined, this.interpolateQueryExpr);
|
return this.templateSrv.replace(string, undefined, this.interpolateQueryExpr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user