diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index 6638ce3e326..0affb9b22e5 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -32,7 +32,7 @@ import { LokiDatasource, REF_ID_DATA_SAMPLES } from './datasource'; import { createLokiDatasource, createMetadataRequest } from './mocks'; import { runSplitQuery } from './querySplitting'; import { parseToNodeNamesArray } from './queryUtils'; -import { LokiOptions, LokiQuery, LokiQueryType, LokiVariableQueryType, SupportingQueryType } from './types'; +import { LokiOptions, LokiQuery, LokiQueryType, LokiVariableQueryType, QueryStats, SupportingQueryType } from './types'; import { LokiVariableSupport } from './variables'; jest.mock('@grafana/runtime', () => { @@ -1139,6 +1139,24 @@ describe('LokiDatasource', () => { }); }); }); + + describe('getQueryStats', () => { + it('uses statsMetadataRequest', async () => { + const ds = createLokiDatasource(templateSrvStub); + const spy = jest.spyOn(ds, 'statsMetadataRequest').mockResolvedValue({} as QueryStats); + ds.getQueryStats('{foo="bar"}'); + expect(spy).toHaveBeenCalled(); + }); + }); + + describe('statsMetadataRequest', () => { + it('throws error if url starts with /', () => { + const ds = createLokiDatasource(); + expect(async () => { + await ds.statsMetadataRequest('/index'); + }).rejects.toThrow('invalid metadata request url: /index'); + }); + }); }); describe('applyTemplateVariables', () => { diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index d53fc65f6e6..42685f10ecf 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -422,7 +422,21 @@ export class LokiDatasource } const res = await this.getResource(url, params, options); - return res.data ?? (res || []); + return res.data || []; + } + + // We need a specific metadata method for stats endpoint as it does not return res.data, + // but it returns stats directly in res object. + async statsMetadataRequest( + url: string, + params?: Record, + options?: Partial + ): Promise { + if (url.startsWith('/')) { + throw new Error(`invalid metadata request url: ${url}`); + } + + return await this.getResource(url, params, options); } async getQueryStats(query: string): Promise { @@ -438,7 +452,7 @@ export class LokiDatasource for (const labelMatcher of labelMatchers) { try { - const data = await this.metadataRequest( + const data = await this.statsMetadataRequest( 'index/stats', { query: labelMatcher, start, end }, { showErrorAlert: false }