Skip to content

Commit 6e517b4

Browse files
authored
Merge pull request #4180 from RedisInsight/feature/RI-6363-include-server-name-to-telemetry
RI-6363 include server_name to telemetry
2 parents 575cc46 + 342cbb9 commit 6e517b4

File tree

10 files changed

+68
-8
lines changed

10 files changed

+68
-8
lines changed

redisinsight/api/src/__mocks__/databases.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ export const mockDatabaseOverviewCurrentKeyspace = DatabaseOverviewKeyspace.Curr
232232
export const mockRedisServerInfoDto = {
233233
redis_version: '7.0.5',
234234
redis_mode: 'standalone',
235+
server_name: 'valkey',
235236
os: 'Linux 4.15.0-1087-gcp x86_64',
236237
arch_bits: '64',
237238
tcp_port: '11113',

redisinsight/api/src/modules/database/database.analytics.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ describe('DatabaseAnalytics', () => {
5757
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
5858
databaseIndex: 0,
5959
useDecompression: mockDatabaseWithTlsAuth.compressor,
60+
serverName: 'valkey',
6061
...DEFAULT_REDIS_MODULES_SUMMARY,
6162
},
6263
);
@@ -88,6 +89,7 @@ describe('DatabaseAnalytics', () => {
8889
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
8990
databaseIndex: 0,
9091
useDecompression: mockDatabaseWithTlsAuth.compressor,
92+
serverName: 'valkey',
9193
...DEFAULT_REDIS_MODULES_SUMMARY,
9294
},
9395
);
@@ -127,6 +129,7 @@ describe('DatabaseAnalytics', () => {
127129
version: 20000,
128130
},
129131
customModules: [{ name: 'rediSQL', version: 1 }],
132+
serverName: null,
130133
},
131134
);
132135
});
@@ -166,6 +169,7 @@ describe('DatabaseAnalytics', () => {
166169
version: 20000,
167170
},
168171
customModules: [{ name: 'rediSQL', version: 1 }],
172+
serverName: null,
169173
},
170174
);
171175
});

redisinsight/api/src/modules/database/database.analytics.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export class DatabaseAnalytics extends TelemetryBaseService {
5151
timeout: instance.timeout / 1_000, // milliseconds to seconds
5252
databaseIndex: instance.db || 0,
5353
useDecompression: instance.compressor || null,
54+
serverName: additionalInfo?.server?.server_name || null,
5455
...modulesSummary,
5556
},
5657
);

redisinsight/api/src/modules/database/database.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ export class DatabaseService {
184184
database,
185185
);
186186
const redisInfo = await this.databaseInfoProvider.getRedisGeneralInfo(client);
187+
187188
this.analytics.sendInstanceAddedEvent(database, redisInfo);
188189
await client.disconnect();
189190
} catch (e) {

redisinsight/api/src/modules/database/models/database-overview.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@ export class DatabaseOverview {
5454
type: Number,
5555
})
5656
cpuUsagePercentage?: number;
57+
58+
@ApiProperty({
59+
description: 'Database server name',
60+
type: String,
61+
})
62+
serverName?: string;
5763
}

redisinsight/api/src/modules/database/providers/database-overview.provider.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const mockGetTotalResponse1 = 1;
5555

5656
export const mockDatabaseOverview: DatabaseOverview = {
5757
version: mockServerInfo.redis_version,
58+
serverName: null,
5859
usedMemory: 1,
5960
totalKeys: 2,
6061
totalKeysPerDb: {
@@ -110,6 +111,28 @@ describe('OverviewService', () => {
110111
networkOutKbps: undefined,
111112
});
112113
});
114+
it('should return overview with serverName if server_name is present in redis info', async () => {
115+
const redisInfoReplyWithServerName = `${mockStandaloneRedisInfoReply.slice(0, 11)}server_name:valkey\r\n${mockStandaloneRedisInfoReply.slice(11)}`;
116+
when(standaloneClient.sendCommand)
117+
.calledWith(['info'], { replyEncoding: 'utf8' })
118+
.mockResolvedValue(redisInfoReplyWithServerName);
119+
120+
const result = await service.getOverview(mockClientMetadata, standaloneClient, mockCurrentKeyspace);
121+
122+
expect(result).toEqual({
123+
...mockDatabaseOverview,
124+
version: '6.0.5',
125+
serverName: 'valkey',
126+
connectedClients: 1,
127+
totalKeys: 1,
128+
totalKeysPerDb: undefined,
129+
usedMemory: 1000000,
130+
cpuUsagePercentage: undefined,
131+
opsPerSecond: undefined,
132+
networkInKbps: undefined,
133+
networkOutKbps: undefined,
134+
});
135+
});
113136
it('should return total 0 and empty total per db object', async () => {
114137
spyGetNodeInfo.mockResolvedValueOnce({
115138
...mockNodeInfo,

redisinsight/api/src/modules/database/providers/database-overview.provider.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export class DatabaseOverviewProvider {
5555

5656
return {
5757
version: this.getVersion(nodesInfo),
58+
serverName: this.getServerName(nodesInfo),
5859
totalKeys,
5960
totalKeysPerDb,
6061
usedMemory: this.calculateUsedMemory(nodesInfo),
@@ -126,6 +127,15 @@ export class DatabaseOverviewProvider {
126127
return get(nodes, [0, 'server', 'redis_version'], null);
127128
}
128129

130+
/**
131+
* Get server_name from the first shard in the list
132+
* @param nodes
133+
* @private
134+
*/
135+
private getServerName(nodes = []): string {
136+
return get(nodes, [0, 'server', 'server_name'], null);
137+
}
138+
129139
/**
130140
* Sum of current ops per second (instantaneous_ops_per_sec) for all shards
131141
* @param nodes

redisinsight/api/test/api/database/GET-databases-id-overview.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const endpoint = (id = constants.TEST_INSTANCE_ID) =>
77

88
const responseSchema = Joi.object().keys({
99
version: Joi.string().required(),
10+
serverName: Joi.string().allow(null),
1011
totalKeys: Joi.number().integer().allow(null),
1112
totalKeysPerDb: Joi.object().allow(null),
1213
usedMemory: Joi.number().integer().allow(null),

redisinsight/ui/src/slices/interfaces/instances.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ export interface DatabaseConfigInfo {
307307
networkInKbps?: Nullable<number>
308308
networkOutKbps?: Nullable<number>
309309
cpuUsagePercentage?: Nullable<number>
310+
serverName?: Nullable<string>
310311
}
311312

312313
export interface InitialStateInstances {

redisinsight/ui/src/telemetry/telemetryUtils.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,41 +20,53 @@ import {
2020
import { TelemetryEvent } from './events'
2121
import { checkIsAnalyticsGranted } from './checkAnalytics'
2222

23-
export const getProvider = (dbId: string): Maybe<string> => {
23+
export const getProviderData = (dbId: string): {
24+
provider: Maybe<string>,
25+
serverName: Maybe<string>
26+
} => {
27+
let provider
28+
let serverName
2429
const instance = get(store.getState(), 'connections.instances.connectedInstance')
25-
return (instance.id === dbId) ? instance.provider : undefined
30+
if (instance.id === dbId) {
31+
provider = instance?.provider
32+
const instanceOverview = get(store.getState(), 'connections.instances.instanceOverview')
33+
serverName = instanceOverview?.serverName || undefined
34+
}
35+
return { provider, serverName }
2636
}
2737

2838
const TELEMETRY_EMPTY_VALUE = 'none'
2939

3040
const sendEventTelemetry = async ({ event, eventData = {}, traits = {} }: ITelemetrySendEvent) => {
41+
let providerData
3142
try {
3243
const isAnalyticsGranted = checkIsAnalyticsGranted()
3344
if (!isAnalyticsGranted) {
3445
return
3546
}
3647

37-
if (!eventData.provider && eventData.databaseId) {
38-
eventData.provider = getProvider(eventData.databaseId)
48+
if (eventData.databaseId) {
49+
providerData = getProviderData(eventData.databaseId)
3950
}
4051
await apiService.post(`${ApiEndpoints.ANALYTICS_SEND_EVENT}`,
41-
{ event, eventData, traits })
52+
{ event, eventData: { ...providerData, ...eventData }, traits })
4253
} catch (e) {
4354
// continue regardless of error
4455
}
4556
}
4657

4758
const sendPageViewTelemetry = async ({ name, eventData = {} }: ITelemetrySendPageView) => {
4859
try {
60+
let providerData
4961
const isAnalyticsGranted = checkIsAnalyticsGranted()
5062
if (!isAnalyticsGranted) {
5163
return
5264
}
53-
if (!eventData.provider && eventData.databaseId) {
54-
eventData.provider = getProvider(eventData.databaseId)
65+
if (eventData.databaseId) {
66+
providerData = getProviderData(eventData.databaseId)
5567
}
5668
await apiService.post(`${ApiEndpoints.ANALYTICS_SEND_PAGE}`,
57-
{ event: name, eventData })
69+
{ event: name, eventData: { ...providerData, ...eventData } })
5870
} catch (e) {
5971
// continue regardless of error
6072
}

0 commit comments

Comments
 (0)