Loki: pass backendSrv request options (#95608)

* chore: allow passthrough of options, reject promise on error
This commit is contained in:
Galen Kistler 2024-10-30 08:50:51 -05:00 committed by GitHub
parent 90d2f4659e
commit 777979965d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 20 deletions

View File

@ -326,7 +326,7 @@ describe('Language completion provider', () => {
const requestSpy = jest.spyOn(provider, 'request');
const labelValues = await provider.fetchDetectedLabelValues(labelName, options);
expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true);
expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true, undefined);
expect(labelValues).toEqual(expectedResponse);
});
@ -340,7 +340,7 @@ describe('Language completion provider', () => {
const nextLabelValues = await provider.fetchDetectedLabelValues(labelName, options);
expect(requestSpy).toHaveBeenCalledTimes(1);
expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true);
expect(requestSpy).toHaveBeenCalledWith(`detected_field/${labelName}/values`, expectedOptions, true, undefined);
expect(nextLabelValues).toEqual(expectedResponse);
});
@ -349,7 +349,12 @@ describe('Language completion provider', () => {
const requestSpy = jest.spyOn(provider, 'request');
await provider.fetchDetectedLabelValues('`\\"testkey', options);
expect(requestSpy).toHaveBeenCalledWith('detected_field/%60%5C%22testkey/values', expectedOptions, true);
expect(requestSpy).toHaveBeenCalledWith(
'detected_field/%60%5C%22testkey/values',
expectedOptions,
true,
undefined
);
});
it('should cache by label name', async () => {
@ -448,7 +453,7 @@ describe('Request URL', () => {
const instance = new LanguageProvider(datasourceWithLabels);
instance.fetchLabels();
const expectedUrl = 'labels';
expect(datasourceSpy).toHaveBeenCalledWith(expectedUrl, rangeParams);
expect(datasourceSpy).toHaveBeenCalledWith(expectedUrl, rangeParams, undefined);
});
});

View File

@ -2,7 +2,7 @@ import { flatten } from 'lodash';
import { LRUCache } from 'lru-cache';
import { LanguageProvider, AbstractQuery, KeyValue, getDefaultTimeRange, TimeRange, ScopedVars } from '@grafana/data';
import { config } from '@grafana/runtime';
import { BackendSrvRequest, config } from '@grafana/runtime';
import { DEFAULT_MAX_LINES_SAMPLE, LokiDatasource } from './datasource';
import { abstractQueryToExpr, mapAbstractOperatorsToOp, processLabels } from './languageUtils';
@ -44,13 +44,19 @@ export default class LokiLanguageProvider extends LanguageProvider {
Object.assign(this, initialValues);
}
request = async (url: string, params?: Record<string, string | number>, throwError?: boolean) => {
request = async (
url: string,
params?: Record<string, string | number>,
throwError?: boolean,
requestOptions?: Partial<BackendSrvRequest>
) => {
try {
return await this.datasource.metadataRequest(url, params);
return await this.datasource.metadataRequest(url, params, requestOptions);
} catch (error) {
console.error(error);
if (throwError) {
throw error;
} else {
console.error(error);
}
}
@ -245,20 +251,27 @@ export default class LokiLanguageProvider extends LanguageProvider {
async fetchDetectedLabelValues(
labelName: string,
options?: { expr?: string; timeRange?: TimeRange; limit?: number; scopedVars?: ScopedVars; throwError?: boolean }
): Promise<string[]> {
queryOptions?: {
expr?: string;
timeRange?: TimeRange;
limit?: number;
scopedVars?: ScopedVars;
throwError?: boolean;
},
requestOptions?: Partial<BackendSrvRequest>
): Promise<string[] | Error> {
const label = encodeURIComponent(this.datasource.interpolateString(labelName));
const interpolatedExpr =
options?.expr && options.expr !== EMPTY_SELECTOR
? this.datasource.interpolateString(options.expr, options.scopedVars)
queryOptions?.expr && queryOptions.expr !== EMPTY_SELECTOR
? this.datasource.interpolateString(queryOptions.expr, queryOptions.scopedVars)
: undefined;
const url = `detected_field/${label}/values`;
const range = options?.timeRange ?? this.getDefaultTimeRange();
const range = queryOptions?.timeRange ?? this.getDefaultTimeRange();
const rangeParams = this.datasource.getTimeRangeParams(range);
const { start, end } = rangeParams;
const params: KeyValue<string | number> = { start, end, limit: options?.limit ?? 1000 };
const params: KeyValue<string | number> = { start, end, limit: queryOptions?.limit ?? 1000 };
let paramCacheKey = label;
if (interpolatedExpr) {
@ -280,9 +293,9 @@ export default class LokiLanguageProvider extends LanguageProvider {
return labelValuesPromise;
}
labelValuesPromise = new Promise(async (resolve) => {
labelValuesPromise = new Promise(async (resolve, reject) => {
try {
const data = await this.request(url, params, options?.throwError);
const data = await this.request(url, params, queryOptions?.throwError, requestOptions);
if (Array.isArray(data)) {
const labelValues = data.slice().sort();
this.detectedFieldValuesCache.set(cacheKey, labelValues);
@ -290,10 +303,11 @@ export default class LokiLanguageProvider extends LanguageProvider {
resolve(labelValues);
}
} catch (error) {
if (queryOptions?.throwError) {
reject(error);
} else {
console.error(error);
resolve([]);
if (options?.throwError) {
throw error;
}
}
});