Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions redisinsight/api/src/__mocks__/databases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const mockDatabaseOverviewCurrentKeyspace = DatabaseOverviewKeyspace.Curr
export const mockRedisServerInfoDto = {
redis_version: '7.0.5',
redis_mode: 'standalone',
server_name: 'valkey',
os: 'Linux 4.15.0-1087-gcp x86_64',
arch_bits: '64',
tcp_port: '11113',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe('DatabaseAnalytics', () => {
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
databaseIndex: 0,
useDecompression: mockDatabaseWithTlsAuth.compressor,
serverName: 'valkey',
...DEFAULT_REDIS_MODULES_SUMMARY,
},
);
Expand Down Expand Up @@ -88,6 +89,7 @@ describe('DatabaseAnalytics', () => {
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
databaseIndex: 0,
useDecompression: mockDatabaseWithTlsAuth.compressor,
serverName: 'valkey',
...DEFAULT_REDIS_MODULES_SUMMARY,
},
);
Expand Down Expand Up @@ -127,6 +129,7 @@ describe('DatabaseAnalytics', () => {
version: 20000,
},
customModules: [{ name: 'rediSQL', version: 1 }],
serverName: null,
},
);
});
Expand Down Expand Up @@ -166,6 +169,7 @@ describe('DatabaseAnalytics', () => {
version: 20000,
},
customModules: [{ name: 'rediSQL', version: 1 }],
serverName: null,
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class DatabaseAnalytics extends TelemetryBaseService {
timeout: instance.timeout / 1_000, // milliseconds to seconds
databaseIndex: instance.db || 0,
useDecompression: instance.compressor || null,
serverName: additionalInfo?.server?.server_name || null,
...modulesSummary,
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ export class DatabaseService {
database,
);
const redisInfo = await this.databaseInfoProvider.getRedisGeneralInfo(client);

this.analytics.sendInstanceAddedEvent(database, redisInfo);
await client.disconnect();
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ export class DatabaseOverview {
type: Number,
})
cpuUsagePercentage?: number;

@ApiProperty({
description: 'Database server name',
type: String,
})
serverName?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const mockGetTotalResponse1 = 1;

export const mockDatabaseOverview: DatabaseOverview = {
version: mockServerInfo.redis_version,
serverName: null,
usedMemory: 1,
totalKeys: 2,
totalKeysPerDb: {
Expand Down Expand Up @@ -110,6 +111,28 @@ describe('OverviewService', () => {
networkOutKbps: undefined,
});
});
it('should return overview with serverName if server_name is present in redis info', async () => {
const redisInfoReplyWithServerName = `${mockStandaloneRedisInfoReply.slice(0, 11)}server_name:valkey\r\n${mockStandaloneRedisInfoReply.slice(11)}`;
when(standaloneClient.sendCommand)
.calledWith(['info'], { replyEncoding: 'utf8' })
.mockResolvedValue(redisInfoReplyWithServerName);

const result = await service.getOverview(mockClientMetadata, standaloneClient, mockCurrentKeyspace);

expect(result).toEqual({
...mockDatabaseOverview,
version: '6.0.5',
serverName: 'valkey',
connectedClients: 1,
totalKeys: 1,
totalKeysPerDb: undefined,
usedMemory: 1000000,
cpuUsagePercentage: undefined,
opsPerSecond: undefined,
networkInKbps: undefined,
networkOutKbps: undefined,
});
});
it('should return total 0 and empty total per db object', async () => {
spyGetNodeInfo.mockResolvedValueOnce({
...mockNodeInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class DatabaseOverviewProvider {

return {
version: this.getVersion(nodesInfo),
serverName: this.getServerName(nodesInfo),
totalKeys,
totalKeysPerDb,
usedMemory: this.calculateUsedMemory(nodesInfo),
Expand Down Expand Up @@ -126,6 +127,15 @@ export class DatabaseOverviewProvider {
return get(nodes, [0, 'server', 'redis_version'], null);
}

/**
* Get server_name from the first shard in the list
* @param nodes
* @private
*/
private getServerName(nodes = []): string {
return get(nodes, [0, 'server', 'server_name'], null);
}

/**
* Sum of current ops per second (instantaneous_ops_per_sec) for all shards
* @param nodes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const endpoint = (id = constants.TEST_INSTANCE_ID) =>

const responseSchema = Joi.object().keys({
version: Joi.string().required(),
serverName: Joi.string().allow(null),
totalKeys: Joi.number().integer().allow(null),
totalKeysPerDb: Joi.object().allow(null),
usedMemory: Joi.number().integer().allow(null),
Expand Down
1 change: 1 addition & 0 deletions redisinsight/ui/src/slices/interfaces/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ export interface DatabaseConfigInfo {
networkInKbps?: Nullable<number>
networkOutKbps?: Nullable<number>
cpuUsagePercentage?: Nullable<number>
serverName?: Nullable<string>
}

export interface InitialStateInstances {
Expand Down
28 changes: 20 additions & 8 deletions redisinsight/ui/src/telemetry/telemetryUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,53 @@ import {
import { TelemetryEvent } from './events'
import { checkIsAnalyticsGranted } from './checkAnalytics'

export const getProvider = (dbId: string): Maybe<string> => {
export const getProviderData = (dbId: string): {
provider: Maybe<string>,
serverName: Maybe<string>
} => {
let provider
let serverName
const instance = get(store.getState(), 'connections.instances.connectedInstance')
return (instance.id === dbId) ? instance.provider : undefined
if (instance.id === dbId) {
provider = instance?.provider
const instanceOverview = get(store.getState(), 'connections.instances.instanceOverview')
serverName = instanceOverview?.serverName || undefined
}
return { provider, serverName }
}

const TELEMETRY_EMPTY_VALUE = 'none'

const sendEventTelemetry = async ({ event, eventData = {}, traits = {} }: ITelemetrySendEvent) => {
let providerData
try {
const isAnalyticsGranted = checkIsAnalyticsGranted()
if (!isAnalyticsGranted) {
return
}

if (!eventData.provider && eventData.databaseId) {
eventData.provider = getProvider(eventData.databaseId)
if (eventData.databaseId) {
providerData = getProviderData(eventData.databaseId)
}
await apiService.post(`${ApiEndpoints.ANALYTICS_SEND_EVENT}`,
{ event, eventData, traits })
{ event, eventData: { ...providerData, ...eventData }, traits })
} catch (e) {
// continue regardless of error
}
}

const sendPageViewTelemetry = async ({ name, eventData = {} }: ITelemetrySendPageView) => {
try {
let providerData
const isAnalyticsGranted = checkIsAnalyticsGranted()
if (!isAnalyticsGranted) {
return
}
if (!eventData.provider && eventData.databaseId) {
eventData.provider = getProvider(eventData.databaseId)
if (eventData.databaseId) {
providerData = getProviderData(eventData.databaseId)
}
await apiService.post(`${ApiEndpoints.ANALYTICS_SEND_PAGE}`,
{ event: name, eventData })
{ event: name, eventData: { ...providerData, ...eventData } })
} catch (e) {
// continue regardless of error
}
Expand Down
Loading