diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index dfcc916893e..b8a364f19a6 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -291,10 +291,6 @@ export interface FeatureToggles { */ externalCorePlugins?: boolean; /** - * Sends metrics of public grafana packages usage by plugins - */ - pluginsAPIMetrics?: boolean; - /** * Automatic service account and token setup for plugins */ externalServiceAccounts?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 15313d49837..c96090f0e2d 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -481,13 +481,6 @@ var ( Owner: grafanaPluginsPlatformSquad, Expression: "true", // enabled by default }, - { - Name: "pluginsAPIMetrics", - Description: "Sends metrics of public grafana packages usage by plugins", - FrontendOnly: true, - Stage: FeatureStageExperimental, - Owner: grafanaPluginsPlatformSquad, - }, { Name: "externalServiceAccounts", Description: "Automatic service account and token setup for plugins", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index dc9ec21f9a1..4f50369af09 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -62,7 +62,6 @@ lokiRunQueriesInParallel,privatePreview,@grafana/observability-logs,false,false, wargamesTesting,experimental,@grafana/hosted-grafana-team,false,false,false alertingInsights,GA,@grafana/alerting-squad,false,false,true externalCorePlugins,GA,@grafana/plugins-platform-backend,false,false,false -pluginsAPIMetrics,experimental,@grafana/plugins-platform-backend,false,false,true externalServiceAccounts,preview,@grafana/identity-access-team,false,false,false panelMonitoring,GA,@grafana/dataviz-squad,false,false,true enableNativeHTTPHistogram,experimental,@grafana/grafana-backend-services-squad,false,true,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 987c659c996..7fcbc519d18 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -259,10 +259,6 @@ const ( // Allow core plugins to be loaded as external FlagExternalCorePlugins = "externalCorePlugins" - // FlagPluginsAPIMetrics - // Sends metrics of public grafana packages usage by plugins - FlagPluginsAPIMetrics = "pluginsAPIMetrics" - // FlagExternalServiceAccounts // Automatic service account and token setup for plugins FlagExternalServiceAccounts = "externalServiceAccounts" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 95fcb09e592..c3cf020be00 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -2438,7 +2438,8 @@ "metadata": { "name": "pluginsAPIMetrics", "resourceVersion": "1743693517832", - "creationTimestamp": "2023-09-21T11:36:32Z" + "creationTimestamp": "2023-09-21T11:36:32Z", + "deletionTimestamp": "2025-04-14T09:21:29Z" }, "spec": { "description": "Sends metrics of public grafana packages usage by plugins", diff --git a/public/app/features/plugins/loader/packageMetrics.test.ts b/public/app/features/plugins/loader/packageMetrics.test.ts deleted file mode 100644 index eb06454acaf..00000000000 --- a/public/app/features/plugins/loader/packageMetrics.test.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { logInfo } from '@grafana/runtime'; - -import { trackPackageUsage } from './packageMetrics'; - -jest.mock('@grafana/runtime', () => ({ - logInfo: jest.fn().mockImplementation(), -})); - -// notice each test object has a different key to prevent hitting the cache -const logInfoMock = logInfo as jest.Mock; -const mockUsage = jest.fn(); - -describe('trackPackageUsage', () => { - beforeEach(() => { - logInfoMock.mockClear(); - }); - - describe('With document.currentScript null', () => { - const originalCurrentScript = document.currentScript; - - // set currentScript to null - beforeAll(() => { - Object.defineProperty(document, 'currentScript', { - value: null, - writable: true, - }); - }); - - // restore original currentScript - afterAll(() => { - Object.defineProperty(document, 'currentScript', { - value: originalCurrentScript, - writable: true, - }); - }); - - it('should not log API usage and for non-grafana packages', () => { - const obj = { - foo: 'bar', - }; - const packageName = 'lodash'; - - const result = trackPackageUsage(obj, packageName); - - mockUsage(result.foo); - - expect(logInfoMock).toHaveBeenCalledTimes(0); - }); - - it('should log API usage and return a proxy object for @grafana/data packages', () => { - const obj = { - foo: 'bar', - }; - const packageName = '@grafana/data'; - - const result = trackPackageUsage(obj, packageName); - - mockUsage(result.foo); - - expect(logInfoMock).toHaveBeenCalledTimes(1); - expect(logInfoMock).toHaveBeenLastCalledWith(`Plugin using @grafana/data.foo`, { - key: 'foo', - parent: '@grafana/data', - packageName: '@grafana/data', - }); - expect(result).toEqual(obj); - }); - - it('should log API usage and return a proxy object for app/* packages', () => { - const obj = { - foo: 'bar', - }; - const packageName = 'app/core/test'; - - const result = trackPackageUsage(obj, packageName); - - mockUsage(result.foo); - - expect(logInfoMock).toHaveBeenCalledTimes(1); - expect(logInfoMock).toHaveBeenLastCalledWith(`Plugin using app/core/test.foo`, { - key: 'foo', - parent: 'app/core/test', - packageName: 'app/core/test', - }); - expect(result).toEqual(obj); - }); - - it('should return a proxy object for nested properties', () => { - const obj = { - foo2: { - bar: 'baz', - }, - }; - const packageName = '@grafana/data'; - - const result = trackPackageUsage(obj, packageName); - mockUsage(result.foo2.bar); - - // 2 calls, one for each attribute - expect(logInfoMock).toHaveBeenCalledTimes(2); - - expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo2`, { - key: 'foo2', - parent: '@grafana/data', - packageName: '@grafana/data', - }); - expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo2.bar`, { - key: 'bar', - parent: '@grafana/data.foo2', - packageName: '@grafana/data', - }); - - expect(result.foo2).toEqual(obj.foo2); - }); - - it('should not log API usage for symbols or __useDefault key', () => { - const obj = { - [Symbol('key')]: 'value', - __useDefault: 'default', - }; - const packageName = '@grafana/data'; - - const result = trackPackageUsage(obj, packageName); - - expect(logInfoMock).not.toHaveBeenCalled(); - expect(result).toEqual(obj); - }); - - it('should return the same proxy object for the same nested property', () => { - const obj = { - foo3: { - bar: 'baz', - }, - }; - const packageName = '@grafana/data'; - - const result1 = trackPackageUsage(obj, packageName); - const result2 = trackPackageUsage(obj, packageName); - - mockUsage(result1.foo3); - - expect(logInfoMock).toHaveBeenCalledTimes(1); - expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo3`, { - key: 'foo3', - parent: '@grafana/data', - packageName: '@grafana/data', - }); - mockUsage(result2.foo3.bar); - expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo3.bar`, { - key: 'bar', - parent: '@grafana/data.foo3', - packageName: '@grafana/data', - }); - - expect(result1.foo3).toEqual(obj.foo3); - expect(result2.foo3).toEqual(obj.foo3); - expect(result1.foo3).toBe(result2.foo3); - }); - - it('should not report twice the same key usage', () => { - const obj = { - cacheMe: 'please', - zap: { - cacheMeInner: 'please', - }, - }; - - const result = trackPackageUsage(obj, '@grafana/data'); - - mockUsage(result.cacheMe); - expect(logInfoMock).toHaveBeenCalledTimes(1); - mockUsage(result.cacheMe); - expect(logInfoMock).toHaveBeenCalledTimes(1); - - mockUsage(result.zap); - expect(logInfoMock).toHaveBeenCalledTimes(2); - mockUsage(result.zap); - expect(logInfoMock).toHaveBeenCalledTimes(2); - - mockUsage(result.zap.cacheMeInner); - expect(logInfoMock).toHaveBeenCalledTimes(3); - mockUsage(result.zap.cacheMeInner); - expect(logInfoMock).toHaveBeenCalledTimes(3); - - expect(result).toEqual(obj); - }); - }); - - it('Should skip tracking if document.currentScript is not null', () => { - // Save the original value of the attribute - const originalCurrentScript = document.currentScript; - - // Define a new property on the document object with the mock currentScript - Object.defineProperty(document, 'currentScript', { - value: { - src: 'mocked-script.js', - }, - writable: true, - }); - - const obj = { - lor: 'me', - }; - - const result = trackPackageUsage(obj, '@grafana/data'); - - mockUsage(result.lor); - expect(logInfoMock).not.toHaveBeenCalled(); - - // Restore the original value of the currentScript attribute - Object.defineProperty(document, 'currentScript', { - value: originalCurrentScript, - writable: true, - }); - }); -}); diff --git a/public/app/features/plugins/loader/packageMetrics.ts b/public/app/features/plugins/loader/packageMetrics.ts deleted file mode 100644 index a8ef34e1416..00000000000 --- a/public/app/features/plugins/loader/packageMetrics.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { logInfo } from '@grafana/runtime'; - -const cachedMetricProxies = new WeakMap(); -const trackedKeys: Record = {}; - -function createMetricsProxy(obj: T, parentName: string, packageName: string): T { - const handler: ProxyHandler = { - get(target, key) { - if ( - // plugins are evaluated by SystemJS and not by a browser