From a13ac775b3ebec817d234aeeaddcf47780472612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Thu, 15 Jun 2023 16:38:34 +0200 Subject: [PATCH] [FullStory] Limit number of pageVars (#159725) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../fullstory/src/fullstory_shipper.test.ts | 8 +- .../fullstory/src/fullstory_shipper.ts | 82 ++++++++++++++----- .../shippers/fullstory/tsconfig.json | 3 +- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/packages/analytics/shippers/fullstory/src/fullstory_shipper.test.ts b/packages/analytics/shippers/fullstory/src/fullstory_shipper.test.ts index 6707c509a7e83..4e874b405add1 100644 --- a/packages/analytics/shippers/fullstory/src/fullstory_shipper.test.ts +++ b/packages/analytics/shippers/fullstory/src/fullstory_shipper.test.ts @@ -85,7 +85,6 @@ describe('FullStoryShipper', () => { expect(fullStoryApiMock.setVars).toHaveBeenCalledWith('page', { // eslint-disable-next-line @typescript-eslint/naming-convention cloudId_str: 'test-es-org-id', - org_id_str: 'test-es-org-id', }); }); @@ -94,7 +93,6 @@ describe('FullStoryShipper', () => { expect(fullStoryApiMock.setVars).toHaveBeenCalledWith('page', { // eslint-disable-next-line @typescript-eslint/naming-convention cloudId_str: 'test-es-org-id', - org_id_str: 'test-es-org-id', version_str: '1.2.3', version_major_int: 1, version_minor_int: 2, @@ -102,11 +100,12 @@ describe('FullStoryShipper', () => { }); }); - test('adds the rest of the context to `setVars`', () => { + test('adds the rest of the context to `setVars` (only if they match one of the valid keys)', () => { const context = { userId: 'test-user-id', version: '1.2.3', cloudId: 'test-es-org-id', + labels: { serverless: 'test' }, foo: 'bar', }; fullstoryShipper.extendContext(context); @@ -117,8 +116,7 @@ describe('FullStoryShipper', () => { version_patch_int: 3, // eslint-disable-next-line @typescript-eslint/naming-convention cloudId_str: 'test-es-org-id', - org_id_str: 'test-es-org-id', - foo_str: 'bar', + labels: { serverless_str: 'test' }, }); }); }); diff --git a/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts b/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts index e60686937884a..6c1e11c36542d 100644 --- a/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts +++ b/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts @@ -12,12 +12,39 @@ import type { Event, IShipper, } from '@kbn/analytics-client'; +import { get, has } from 'lodash'; +import { set } from '@kbn/safer-lodash-set'; import type { FullStoryApi } from './types'; import type { FullStorySnippetConfig } from './load_snippet'; import { formatPayload } from './format_payload'; import { loadSnippet } from './load_snippet'; import { getParsedVersion } from './get_parsed_version'; +const PAGE_VARS_KEYS = [ + // Page-specific keys + 'pageName', + 'page', + 'entityId', + 'applicationId', + + // Deployment-specific keys + 'version', // x4, split to version_major, version_minor, version_patch for easier filtering + 'buildNum', // May be useful for Serverless + 'cloudId', + 'deploymentId', + 'cluster_name', + 'cluster_uuid', + 'cluster_version', + 'labels.serverless', + 'license_id', + 'license_status', + 'license_type', + + // Session-specific + 'session_id', + 'preferred_languages', +] as const; + /** * FullStory shipper configuration. */ @@ -62,7 +89,13 @@ export class FullStoryShipper implements IShipper { this.initContext.logger.debug(`Received context ${JSON.stringify(newContext)}`); // FullStory requires different APIs for different type of contexts. - const { userId, isElasticCloudUser, ...nonUserContext } = newContext; + const { + userId, + isElasticCloudUser, + cloudIsElasticStaffOwned, + cloudTrialEndDate, + ...nonUserContext + } = newContext; // Call it only when the userId changes if (userId && userId !== this.lastUserId) { @@ -73,30 +106,37 @@ export class FullStoryShipper implements IShipper { } // User-level context - if (typeof isElasticCloudUser === 'boolean') { - this.initContext.logger.debug( - `Calling FS.setUserVars with isElasticCloudUser ${isElasticCloudUser}` - ); - this.fullStoryApi.setUserVars( - formatPayload({ - isElasticCloudUser, - }) - ); + if ( + typeof isElasticCloudUser === 'boolean' || + typeof cloudIsElasticStaffOwned === 'boolean' || + cloudTrialEndDate + ) { + const userVars = { + isElasticCloudUser, + cloudIsElasticStaffOwned, + cloudTrialEndDate, + }; + this.initContext.logger.debug(`Calling FS.setUserVars with ${JSON.stringify(userVars)}`); + this.fullStoryApi.setUserVars(formatPayload(userVars)); } + // Cherry-picking fields because FS limits the number of fields that can be sent. + // > Note: You can capture up to 20 unique page properties (exclusive of pageName) for any given page + // > and up to 500 unique page properties across all pages. + // https://help.fullstory.com/hc/en-us/articles/1500004101581-FS-setVars-API-Sending-custom-page-data-to-FullStory + const pageVars = PAGE_VARS_KEYS.reduce((acc, key) => { + if (has(nonUserContext, key)) { + set(acc, key, get(nonUserContext, key)); + } + return acc; + }, {} as Partial> & Record); + // Event-level context. At the moment, only the scope `page` is supported by FullStory for webapps. - if (Object.keys(nonUserContext).length) { - // Keeping these fields for backwards compatibility. - if (nonUserContext.applicationId) nonUserContext.app_id = nonUserContext.applicationId; - if (nonUserContext.entityId) nonUserContext.ent_id = nonUserContext.entityId; - if (nonUserContext.cloudId) nonUserContext.org_id = nonUserContext.cloudId; - - this.initContext.logger.debug( - `Calling FS.setVars with context ${JSON.stringify(nonUserContext)}` - ); + if (Object.keys(pageVars).length) { + this.initContext.logger.debug(`Calling FS.setVars with context ${JSON.stringify(pageVars)}`); this.fullStoryApi.setVars('page', { - ...formatPayload(nonUserContext), - ...(nonUserContext.version ? getParsedVersion(nonUserContext.version) : {}), + ...formatPayload(pageVars), + ...(pageVars.version ? getParsedVersion(pageVars.version) : {}), }); } } diff --git a/packages/analytics/shippers/fullstory/tsconfig.json b/packages/analytics/shippers/fullstory/tsconfig.json index f3b62b9be125f..00a680d9c6f2c 100644 --- a/packages/analytics/shippers/fullstory/tsconfig.json +++ b/packages/analytics/shippers/fullstory/tsconfig.json @@ -12,7 +12,8 @@ ], "kbn_references": [ "@kbn/analytics-client", - "@kbn/logging-mocks" + "@kbn/logging-mocks", + "@kbn/safer-lodash-set" ], "exclude": [ "target/**/*",