diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index e2a79ca824f..c2054a6801c 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -761,6 +761,10 @@ export interface FeatureToggles { */ prometheusSpecialCharsInLabelValues?: boolean; /** + * Uses new resource api which has automatic feature detection and performance improvements + */ + prometheusResourceClient?: boolean; + /** * Enables the extension admin page regardless of development mode */ enableExtensionsAdminPage?: boolean; diff --git a/packages/grafana-prometheus/src/datasource.ts b/packages/grafana-prometheus/src/datasource.ts index 492919dfd4c..bc2b6db1f1f 100644 --- a/packages/grafana-prometheus/src/datasource.ts +++ b/packages/grafana-prometheus/src/datasource.ts @@ -126,7 +126,8 @@ export class PrometheusDatasource this.exemplarTraceIdDestinations = instanceSettings.jsonData.exemplarTraceIdDestinations; this.hasIncrementalQuery = instanceSettings.jsonData.incrementalQuerying ?? false; this.ruleMappings = {}; - this.languageProvider = languageProvider ?? new PrometheusLanguageProvider(this); + this.languageProvider = + languageProvider ?? new PrometheusLanguageProvider(this, config.featureToggles.prometheusResourceClient); this.lookupsDisabled = instanceSettings.jsonData.disableMetricsLookup ?? false; this.customQueryParameters = new URLSearchParams(instanceSettings.jsonData.customQueryParameters); this.datasourceConfigurationPrometheusFlavor = instanceSettings.jsonData.prometheusType; diff --git a/packages/grafana-prometheus/src/language_provider.test.ts b/packages/grafana-prometheus/src/language_provider.test.ts index fe6525b2299..272a3337f59 100644 --- a/packages/grafana-prometheus/src/language_provider.test.ts +++ b/packages/grafana-prometheus/src/language_provider.test.ts @@ -757,14 +757,13 @@ describe('PrometheusLanguageProvider with feature toggle', () => { it('should use resource client start when feature toggle is enabled', async () => { const provider = new PrometheusLanguageProvider(defaultDatasource, true); const mockMetadata = { metric1: { type: 'counter', help: 'help text' } }; - + // Mock the resource client's start method const resourceClientStartSpy = jest.spyOn(provider['_resourceClient'], 'start'); - const queryMetadataSpy = jest.spyOn(provider as any, '_queryMetadata') - .mockResolvedValue(mockMetadata); - + const queryMetadataSpy = jest.spyOn(provider as any, '_queryMetadata').mockResolvedValue(mockMetadata); + await provider.start(); - + expect(resourceClientStartSpy).toHaveBeenCalled(); expect(queryMetadataSpy).toHaveBeenCalled(); expect(provider.retrieveMetricsMetadata()).toEqual(mockMetadata); @@ -773,17 +772,14 @@ describe('PrometheusLanguageProvider with feature toggle', () => { it('should use legacy API path when feature toggle is disabled', async () => { const provider = new PrometheusLanguageProvider(defaultDatasource, false); const metrics = ['metric1', 'metric2']; - + // Mock the legacy methods - const fetchLabelValuesSpy = jest.spyOn(provider, 'fetchLabelValues') - .mockResolvedValue(metrics); - const loadMetricsMetadataSpy = jest.spyOn(provider, 'loadMetricsMetadata') - .mockResolvedValue(); - const fetchLabelsSpy = jest.spyOn(provider, 'fetchLabels') - .mockResolvedValue(['label1', 'label2']); - + const fetchLabelValuesSpy = jest.spyOn(provider, 'fetchLabelValues').mockResolvedValue(metrics); + const loadMetricsMetadataSpy = jest.spyOn(provider, 'loadMetricsMetadata').mockResolvedValue(); + const fetchLabelsSpy = jest.spyOn(provider, 'fetchLabels').mockResolvedValue(['label1', 'label2']); + await provider.start(); - + expect(fetchLabelValuesSpy).toHaveBeenCalledWith(expect.any(Object), '__name__'); expect(loadMetricsMetadataSpy).toHaveBeenCalled(); expect(fetchLabelsSpy).toHaveBeenCalled(); @@ -796,8 +792,7 @@ describe('PrometheusLanguageProvider with feature toggle', () => { it('should fetch and store metadata', async () => { const provider = new PrometheusLanguageProvider(defaultDatasource, true); const mockMetadata = { metric1: { type: 'counter', help: 'help text' } }; - const queryMetadataSpy = jest.spyOn(provider as any, '_queryMetadata') - .mockResolvedValue(mockMetadata); + const queryMetadataSpy = jest.spyOn(provider as any, '_queryMetadata').mockResolvedValue(mockMetadata); const result = await provider.queryMetricsMetadata(); @@ -813,7 +808,8 @@ describe('PrometheusLanguageProvider with feature toggle', () => { it('should delegate to resource client queryLabelKeys', async () => { const provider = new PrometheusLanguageProvider(defaultDatasource, true); - const resourceClientSpy = jest.spyOn(provider['_resourceClient'], 'queryLabelKeys') + const resourceClientSpy = jest + .spyOn(provider['_resourceClient'], 'queryLabelKeys') .mockResolvedValue(['label1', 'label2']); const result = await provider.queryLabelKeys(timeRange, '{job="grafana"}'); @@ -824,7 +820,8 @@ describe('PrometheusLanguageProvider with feature toggle', () => { it('should delegate to resource client queryLabelValues', async () => { const provider = new PrometheusLanguageProvider(defaultDatasource, true); - const resourceClientSpy = jest.spyOn(provider['_resourceClient'], 'queryLabelValues') + const resourceClientSpy = jest + .spyOn(provider['_resourceClient'], 'queryLabelValues') .mockResolvedValue(['value1', 'value2']); const result = await provider.queryLabelValues(timeRange, 'job', '{job="grafana"}'); @@ -842,7 +839,7 @@ describe('PrometheusLanguageProvider with feature toggle', () => { metrics: ['metric1', 'metric2'], labelKeys: ['label1', 'label2'], }; - + // Mock the resource client properties Object.defineProperty(provider, '_resourceClient', { value: mockResourceClient, diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 1bdb9bb20d3..94a397d96e5 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1303,6 +1303,13 @@ var ( Stage: FeatureStageExperimental, Owner: grafanaOSSBigTent, }, + { + Name: "prometheusResourceClient", + Description: "Uses new resource api which has automatic feature detection and performance improvements", + FrontendOnly: true, + Stage: FeatureStageExperimental, + Owner: grafanaOSSBigTent, + }, { Name: "enableExtensionsAdminPage", Description: "Enables the extension admin page regardless of development mode", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 5123d14872a..32877189a2e 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -170,6 +170,7 @@ playlistsReconciler,experimental,@grafana/grafana-app-platform-squad,false,true, passwordlessMagicLinkAuthentication,experimental,@grafana/identity-access-team,false,false,false exploreMetricsRelatedLogs,experimental,@grafana/observability-metrics,false,false,true prometheusSpecialCharsInLabelValues,experimental,@grafana/oss-big-tent,false,false,true +prometheusResourceClient,experimental,@grafana/oss-big-tent,false,false,true enableExtensionsAdminPage,experimental,@grafana/plugins-platform-backend,false,true,false enableSCIM,experimental,@grafana/identity-access-team,false,false,false crashDetection,experimental,@grafana/observability-traces-and-profiling,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 83f95f37f1e..51152d069d9 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -691,6 +691,10 @@ const ( // Adds support for quotes and special characters in label values for Prometheus queries FlagPrometheusSpecialCharsInLabelValues = "prometheusSpecialCharsInLabelValues" + // FlagPrometheusResourceClient + // Uses new resource api which has automatic feature detection and performance improvements + FlagPrometheusResourceClient = "prometheusResourceClient" + // FlagEnableExtensionsAdminPage // Enables the extension admin page regardless of development mode FlagEnableExtensionsAdminPage = "enableExtensionsAdminPage" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 4702b756557..a37387d21a8 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -2640,6 +2640,33 @@ "frontend": true } }, + { + "metadata": { + "name": "prometheusLanguageProviderResourceClient", + "resourceVersion": "1748422985998", + "creationTimestamp": "2025-05-28T09:03:05Z", + "deletionTimestamp": "2025-05-28T09:04:52Z" + }, + "spec": { + "description": "Uses new resource api which has automatic feature detection and performance improvements", + "stage": "experimental", + "codeowner": "@grafana/oss-big-tent", + "frontend": true + } + }, + { + "metadata": { + "name": "prometheusResourceClient", + "resourceVersion": "1748423092714", + "creationTimestamp": "2025-05-28T09:04:52Z" + }, + "spec": { + "description": "Uses new resource api which has automatic feature detection and performance improvements", + "stage": "experimental", + "codeowner": "@grafana/oss-big-tent", + "frontend": true + } + }, { "metadata": { "name": "prometheusRunQueriesInParallel",