prometheus: use getSeriesValues in metrics selector (#105361)

When we have labels selected and want to refresh the list of metrics that match this grafana would use an expensive
/api/v1/series call instead of /api/v1/label/__name__/values with matchers, even if the datasource is configured to be
ble to use matchers in label values calls.

Signed-off-by: Michael Hoffmann <mhoffmann@cloudflare.com>
This commit is contained in:
Michael Hoffmann
2025-05-20 12:09:08 +02:00
committed by GitHub
parent 546f0c2675
commit 32bd9e22ee
4 changed files with 6 additions and 4 deletions

View File

@ -10,6 +10,7 @@ export class EmptyLanguageProviderMock {
getLabelKeys = jest.fn().mockReturnValue([]);
getLabelValues = jest.fn().mockReturnValue([]);
getSeries = jest.fn().mockReturnValue({ __name__: [] });
getSeriesValues = jest.fn().mockReturnValue([]);
fetchSeries = jest.fn().mockReturnValue([]);
fetchSeriesLabels = jest.fn().mockReturnValue([]);
fetchSeriesLabelsMatch = jest.fn().mockReturnValue([]);

View File

@ -33,6 +33,7 @@ const createMockDatasource = () => {
fetchSeriesValuesWithMatch: jest.fn().mockResolvedValue(['value1', 'value2']),
getLabelValues: jest.fn().mockResolvedValue(['value1', 'value2']),
getSeries: jest.fn().mockResolvedValue({ __name__: ['metric1', 'metric2'] }),
getSeriesValues: jest.fn().mockResolvedValue(['metric1', 'metric2']),
loadMetricsMetadata: jest.fn().mockResolvedValue({}),
metricsMetadata: { metric1: { type: 'counter', help: 'help text' } },
},

View File

@ -244,7 +244,7 @@ async function getMetrics(
let metrics: string[];
if (query.labels.length > 0) {
const expr = promQueryModeller.renderLabels(query.labels);
metrics = (await datasource.languageProvider.getSeries(timeRange, expr, true))['__name__'] ?? [];
metrics = (await datasource.languageProvider.getSeriesValues(timeRange, '__name__', expr)) ?? [];
} else {
metrics = (await datasource.languageProvider.getLabelValues(timeRange, '__name__')) ?? [];
}

View File

@ -99,10 +99,10 @@ describe('PromQueryBuilder', () => {
});
await openMetricSelect(container);
await waitFor(() =>
expect(languageProvider.getSeries).toHaveBeenCalledWith(
expect(languageProvider.getSeriesValues).toHaveBeenCalledWith(
expect.anything(),
'{label_name="label_value"}',
expect.anything()
expect.anything(),
'{label_name="label_value"}'
)
);
});