Plugins: Only track metrics for grafana packages and core packages (#77785)

* Plugins: Only track metrics for grafana packages and core packages

* Move bind after cache check

* Update tests for metrics tracking
This commit is contained in:
Esteban Beltran 2023-11-07 13:56:26 +01:00 committed by GitHub
parent b7f854a06c
commit 9585e2b19c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 24 deletions

View File

@ -34,21 +34,53 @@ describe('trackPackageUsage', () => {
});
});
it('should log API usage and return a proxy object', () => {
it('should not log API usage and for non-grafana packages', () => {
const obj = {
foo: 'bar',
};
const packageName = 'your-package';
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 your-package.foo`, {
expect(logInfoMock).toHaveBeenLastCalledWith(`Plugin using @grafana/data.foo`, {
key: 'foo',
parent: 'your-package',
packageName: 'your-package',
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);
});
@ -59,7 +91,7 @@ describe('trackPackageUsage', () => {
bar: 'baz',
},
};
const packageName = 'your-package';
const packageName = '@grafana/data';
const result = trackPackageUsage(obj, packageName);
mockUsage(result.foo2.bar);
@ -67,15 +99,15 @@ describe('trackPackageUsage', () => {
// 2 calls, one for each attribute
expect(logInfoMock).toHaveBeenCalledTimes(2);
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using your-package.foo2`, {
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo2`, {
key: 'foo2',
parent: 'your-package',
packageName: 'your-package',
parent: '@grafana/data',
packageName: '@grafana/data',
});
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using your-package.foo2.bar`, {
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo2.bar`, {
key: 'bar',
parent: 'your-package.foo2',
packageName: 'your-package',
parent: '@grafana/data.foo2',
packageName: '@grafana/data',
});
expect(result.foo2).toEqual(obj.foo2);
@ -86,7 +118,7 @@ describe('trackPackageUsage', () => {
[Symbol('key')]: 'value',
__useDefault: 'default',
};
const packageName = 'your-package';
const packageName = '@grafana/data';
const result = trackPackageUsage(obj, packageName);
@ -100,7 +132,7 @@ describe('trackPackageUsage', () => {
bar: 'baz',
},
};
const packageName = 'your-package';
const packageName = '@grafana/data';
const result1 = trackPackageUsage(obj, packageName);
const result2 = trackPackageUsage(obj, packageName);
@ -108,16 +140,16 @@ describe('trackPackageUsage', () => {
mockUsage(result1.foo3);
expect(logInfoMock).toHaveBeenCalledTimes(1);
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using your-package.foo3`, {
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo3`, {
key: 'foo3',
parent: 'your-package',
packageName: 'your-package',
parent: '@grafana/data',
packageName: '@grafana/data',
});
mockUsage(result2.foo3.bar);
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using your-package.foo3.bar`, {
expect(logInfoMock).toHaveBeenCalledWith(`Plugin using @grafana/data.foo3.bar`, {
key: 'bar',
parent: 'your-package.foo3',
packageName: 'your-package',
parent: '@grafana/data.foo3',
packageName: '@grafana/data',
});
expect(result1.foo3).toEqual(obj.foo3);
@ -133,7 +165,7 @@ describe('trackPackageUsage', () => {
},
};
const result = trackPackageUsage(obj, 'your-package');
const result = trackPackageUsage(obj, '@grafana/data');
mockUsage(result.cacheMe);
expect(logInfoMock).toHaveBeenCalledTimes(1);
@ -170,7 +202,7 @@ describe('trackPackageUsage', () => {
lor: 'me',
};
const result = trackPackageUsage(obj, 'your-package');
const result = trackPackageUsage(obj, '@grafana/data');
mockUsage(result.lor);
expect(logInfoMock).not.toHaveBeenCalled();

View File

@ -32,7 +32,7 @@ function createMetricsProxy<T extends object>(obj: T, parentName: string, packag
}
}
const value = Reflect.get(target, key);
let value = Reflect.get(target, key);
if (value !== null && typeof value === 'object' && !(value instanceof RegExp)) {
if (!cachedMetricProxies.has(value)) {
@ -40,6 +40,11 @@ function createMetricsProxy<T extends object>(obj: T, parentName: string, packag
}
return cachedMetricProxies.get(value);
}
// proxies don't play nice with functions scopes
if (typeof value === 'function') {
value = value.bind(target);
}
return value;
},
};
@ -51,6 +56,11 @@ function createMetricsProxy<T extends object>(obj: T, parentName: string, packag
return obj;
}
const trackPackagesRe = /^(@grafana|app\/)/;
export function trackPackageUsage<T extends object>(obj: T, packageName: string): T {
return createMetricsProxy(obj, packageName, packageName);
if (trackPackagesRe.test(packageName)) {
return createMetricsProxy(obj, packageName, packageName);
}
return obj;
}