diff --git a/redisinsight/api/src/__mocks__/analytics.ts b/redisinsight/api/src/__mocks__/analytics.ts index 659e31e891..e80bc68e94 100644 --- a/redisinsight/api/src/__mocks__/analytics.ts +++ b/redisinsight/api/src/__mocks__/analytics.ts @@ -1,4 +1,5 @@ export const mockInstancesAnalyticsService = () => ({ + sendInstanceListReceivedEvent: jest.fn(), sendInstanceAddedEvent: jest.fn(), sendInstanceAddFailedEvent: jest.fn(), sendInstanceEditedEvent: jest.fn(), diff --git a/redisinsight/api/src/constants/telemetry-events.ts b/redisinsight/api/src/constants/telemetry-events.ts index b2666b2b1a..b9424b5026 100644 --- a/redisinsight/api/src/constants/telemetry-events.ts +++ b/redisinsight/api/src/constants/telemetry-events.ts @@ -11,6 +11,7 @@ export enum TelemetryEvents { RedisInstanceDeleted = 'CONFIG_DATABASES_DATABASE_DELETED', RedisInstanceEditedByUser = 'CONFIG_DATABASES_DATABASE_EDITED_BY_USER', RedisInstanceConnectionFailed = 'DATABASE_CONNECTION_FAILED', + RedisInstanceListReceived = 'CONFIG_DATABASES_DATABASE_LIST_DISPLAYED', // Events for autodiscovery flows REClusterDiscoverySucceed = 'CONFIG_DATABASES_RE_CLUSTER_AUTODISCOVERY_SUCCEEDED', diff --git a/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.spec.ts b/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.spec.ts index 16e9563bc9..d0d829cd36 100644 --- a/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.spec.ts +++ b/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.spec.ts @@ -53,6 +53,51 @@ describe('InstancesAnalytics', () => { ); }); + describe('sendInstanceListReceivedEvent', () => { + const instance = mockDatabaseInstanceDto; + it('should emit event with one db in the list', () => { + service.sendInstanceListReceivedEvent([instance]); + + expect(sendEventMethod).toHaveBeenCalledWith( + TelemetryEvents.RedisInstanceListReceived, + { + numberOfDatabases: 1, + }, + ); + }); + it('should emit event with several dbs in the list', () => { + service.sendInstanceListReceivedEvent([instance, instance, instance]); + + expect(sendEventMethod).toHaveBeenCalledWith( + TelemetryEvents.RedisInstanceListReceived, + { + numberOfDatabases: 3, + }, + ); + }); + it('should emit event with several empty in the list', () => { + service.sendInstanceListReceivedEvent([]); + + expect(sendEventMethod).toHaveBeenCalledWith( + TelemetryEvents.RedisInstanceListReceived, + { + numberOfDatabases: 0, + }, + ); + }); + it('should emit event with additional data', () => { + service.sendInstanceListReceivedEvent([], { data: 'data' }); + + expect(sendEventMethod).toHaveBeenCalledWith( + TelemetryEvents.RedisInstanceListReceived, + { + numberOfDatabases: 0, + data: 'data', + }, + ); + }); + }); + describe('sendInstanceAddedEvent', () => { it('should emit event with enabled tls', () => { const instance = mockDatabaseInstanceDto; @@ -72,6 +117,8 @@ describe('InstancesAnalytics', () => { numberOfKeysRange: '0 - 500 000', totalMemory: mockRedisGeneralInfo.usedMemory, numberedDatabases: mockRedisGeneralInfo.databases, + numberOfModules: 0, + modules: [], }, ); }); @@ -96,11 +143,13 @@ describe('InstancesAnalytics', () => { numberOfKeysRange: '0 - 500 000', totalMemory: mockRedisGeneralInfo.usedMemory, numberedDatabases: mockRedisGeneralInfo.databases, + numberOfModules: 0, + modules: [], }, ); }); it('should emit event without additional info', () => { - const instance = mockDatabaseInstanceDto; + const instance = { ...mockDatabaseInstanceDto, modules: [{ name: 'search', version: 20000 }] }; service.sendInstanceAddedEvent(instance, { version: mockRedisGeneralInfo.version, }); @@ -119,6 +168,8 @@ describe('InstancesAnalytics', () => { numberOfKeysRange: undefined, totalMemory: undefined, numberedDatabases: undefined, + numberOfModules: 1, + modules: [{ name: 'search', version: 20000 }], }, ); }); diff --git a/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.ts b/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.ts index 8c5f646b75..6f77675631 100644 --- a/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.ts +++ b/redisinsight/api/src/modules/shared/services/instances-business/instances-analytics.service.ts @@ -12,6 +12,23 @@ export class InstancesAnalyticsService extends TelemetryBaseService { super(eventEmitter); } + sendInstanceListReceivedEvent( + instances: DatabaseInstanceResponse[], + additionalData: object = {}, + ): void { + try { + this.sendEvent( + TelemetryEvents.RedisInstanceListReceived, + { + numberOfDatabases: instances.length, + ...additionalData, + }, + ); + } catch (e) { + // continue regardless of error + } + } + sendInstanceAddedEvent( instance: DatabaseInstanceResponse, additionalInfo: RedisDatabaseInfoResponse, @@ -35,6 +52,8 @@ export class InstancesAnalyticsService extends TelemetryBaseService { numberOfKeysRange: getRangeForNumber(additionalInfo.totalKeys, TOTAL_KEYS_BREAKPOINTS), totalMemory: additionalInfo.usedMemory, numberedDatabases: additionalInfo.databases, + numberOfModules: instance.modules.length, + modules: instance.modules, }, ); } catch (e) { diff --git a/redisinsight/api/src/modules/shared/services/instances-business/instances-business.service.ts b/redisinsight/api/src/modules/shared/services/instances-business/instances-business.service.ts index c0c5af17f6..86168533df 100644 --- a/redisinsight/api/src/modules/shared/services/instances-business/instances-business.service.ts +++ b/redisinsight/api/src/modules/shared/services/instances-business/instances-business.service.ts @@ -92,7 +92,9 @@ export class InstancesBusinessService { async getAll(): Promise { try { - return (await this.databasesProvider.getAll()).map(convertEntityToDto); + const result = (await this.databasesProvider.getAll()).map(convertEntityToDto); + this.instancesAnalyticsService.sendInstanceListReceivedEvent(result); + return result; } catch (error) { this.logger.error('Failed to get database instance list.', error); throw new InternalServerErrorException();