update metadata fetch

This commit is contained in:
ismail simsek
2025-05-25 01:44:41 +02:00
parent 03f344c44f
commit eb85cc4ef8
2 changed files with 163 additions and 7 deletions
@@ -725,6 +725,136 @@ describe('Prometheus Language Provider', () => {
);
});
});
describe('getMetricsMetadata', () => {
it('should fetch metadata if not already loaded', async () => {
const mockMetadata = {
metric1: [
{
type: 'counter',
help: 'help text 1',
},
],
metric2: [
{
type: 'gauge',
help: 'help text 2',
},
],
};
const expectedMetadata = {
metric1: {
type: 'counter',
help: 'help text 1',
},
metric2: {
type: 'gauge',
help: 'help text 2',
},
};
const languageProvider = new LanguageProvider({
...defaultDatasource,
metadataRequest: () => ({ data: { data: mockMetadata } }),
} as unknown as PrometheusDatasource);
const requestSpy = jest.spyOn(languageProvider, 'request');
const result = await languageProvider.getMetricsMetadata();
expect(requestSpy).toHaveBeenCalledWith(
'/api/v1/metadata',
{},
{
showErrorAlert: false,
headers: { 'X-Grafana-Cache': 'private, max-age=86400' },
}
);
expect(result).toEqual(expect.objectContaining(expectedMetadata));
});
it('should return cached metadata without fetching if already loaded', async () => {
const mockMetadata = {
metric1: [
{
type: 'counter',
help: 'help text 1',
},
],
};
const expectedMetadata = {
metric1: {
type: 'counter',
help: 'help text 1',
},
};
const languageProvider = new LanguageProvider({
...defaultDatasource,
metadataRequest: () => ({ data: { data: mockMetadata } }),
} as unknown as PrometheusDatasource);
// First call to load metadata
const firstResult = await languageProvider.getMetricsMetadata();
expect(firstResult).toEqual(expect.objectContaining(expectedMetadata));
const requestSpy = jest.spyOn(languageProvider, 'request');
// Second call should use cached data
const result = await languageProvider.getMetricsMetadata();
expect(requestSpy).not.toHaveBeenCalled();
expect(result).toEqual(expect.objectContaining(expectedMetadata));
});
it('should handle empty metadata response', async () => {
const languageProvider = new LanguageProvider({
...defaultDatasource,
metadataRequest: () => ({ data: { data: {} } }),
} as unknown as PrometheusDatasource);
const result = await languageProvider.getMetricsMetadata();
// Even with empty input, fixSummariesMetadata might add some default entries
expect(Object.keys(result).length).toBeGreaterThanOrEqual(0);
});
it('should handle error during metadata fetch', async () => {
jest.spyOn(console, 'error').mockImplementation();
const languageProvider = new LanguageProvider({
...defaultDatasource,
metadataRequest: () => Promise.reject(new Error('Metadata fetch failed')),
} as unknown as PrometheusDatasource);
const result = await languageProvider.getMetricsMetadata();
expect(result).toEqual(undefined);
});
it('should use configured cache duration from datasource', async () => {
const mockDays = 7;
const languageProvider = new LanguageProvider({
...defaultDatasource,
getDaysToCacheMetadata: () => mockDays,
metadataRequest: () => ({ data: { data: {} } }),
} as unknown as PrometheusDatasource);
const requestSpy = jest.spyOn(languageProvider, 'request');
await languageProvider.getMetricsMetadata();
expect(requestSpy).toHaveBeenCalledWith(
'/api/v1/metadata',
{},
{
showErrorAlert: false,
headers: { 'X-Grafana-Cache': `private, max-age=${mockDays * 86400}` },
}
);
});
});
});
describe('removeQuotesIfExist', () => {
@@ -84,13 +84,19 @@ const getDefaultCacheHeaders = (cacheLevel: PrometheusCacheLevel) => {
};
export default class PromQlLanguageProvider extends LanguageProvider {
declare startTask: Promise<any>;
declare labelFetchTs: number;
private _metricsMetadata?: PromMetricsMetadata;
histogramMetrics: string[];
metrics: string[];
/**
* @deprecated Use getMetricsMetadata() method instead
*/
metricsMetadata?: PromMetricsMetadata;
declare startTask: Promise<any>;
datasource: PrometheusDatasource;
labelKeys: string[] = [];
declare labelFetchTs: number;
constructor(datasource: PrometheusDatasource, initialValues?: Partial<PromQlLanguageProvider>) {
super();
@@ -142,7 +148,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
*
* @returns {Promise<PromMetricsMetadata>} Promise that resolves when metadata has been fetched
*/
fetchMetadata = async () => {
private _fetchMetadata = async () => {
const secondsInDay = 86400;
const headers = buildCacheHeaders(this.datasource.getDaysToCacheMetadata() * secondsInDay);
const metadata = await this.request(
@@ -153,8 +159,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
...headers,
}
);
this.metricsMetadata = fixSummariesMetadata(metadata);
return this.metricsMetadata;
return fixSummariesMetadata(metadata);
};
// ===================================
@@ -256,11 +261,32 @@ export default class PromQlLanguageProvider extends LanguageProvider {
// ======================================================================
public getMetricsMetadata = async (): Promise<PromMetricsMetadata> => {
if (!this._metricsMetadata) {
this._metricsMetadata = await this._fetchMetadata();
}
return this._metricsMetadata;
};
// ======================================================================
/**
* @deprecated Use fetchMetadata instead
* @deprecated Use _fetchMetadata instead. If you want metadata itself use getMetricsMetadata() method.
*/
async loadMetricsMetadata() {
this.fetchMetadata();
const secondsInDay = 86400;
const headers = buildCacheHeaders(this.datasource.getDaysToCacheMetadata() * secondsInDay);
this.metricsMetadata = fixSummariesMetadata(
await this.request(
API_V1.METADATA,
{},
{
showErrorAlert: false,
...headers,
}
)
);
}
getLabelKeys(): string[] {