Skip to content

Commit

Permalink
Merge branch 'main' of github.com:jcger/kibana into cases/167651
Browse files Browse the repository at this point in the history
  • Loading branch information
jcger committed Nov 21, 2023
2 parents c166e27 + 5256108 commit 8931e00
Show file tree
Hide file tree
Showing 44 changed files with 1,384 additions and 1,116 deletions.
2 changes: 1 addition & 1 deletion .buildkite/pipelines/artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ steps:
- exit_status: -1
agents:
queue: n2-2
timeout_in_minutes: 60
timeout_in_minutes: 30
if: "build.env('RELEASE_BUILD') == null || build.env('RELEASE_BUILD') == '' || build.env('RELEASE_BUILD') == 'false'"
retry:
automatic:
Expand Down
2 changes: 1 addition & 1 deletion .ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable.
# If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts

ARG NODE_VERSION=20.9.0
ARG NODE_VERSION=18.18.2

FROM node:${NODE_VERSION} AS base

Expand Down
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.9.0
18.18.2
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.9.0
18.18.2
12 changes: 6 additions & 6 deletions WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install
# Setup the Node.js toolchain for the architectures we want to support
node_repositories(
node_repositories = {
"20.9.0-darwin_amd64": ("node-v20.9.0-darwin-x64.tar.gz", "node-v20.9.0-darwin-x64", "fc5b73f2a78c17bbe926cdb1447d652f9f094c79582f1be6471b4b38a2e1ccc8"),
"20.9.0-darwin_arm64": ("node-v20.9.0-darwin-arm64.tar.gz", "node-v20.9.0-darwin-arm64", "31d2d46ae8d8a3982f54e2ff1e60c2e4a8e80bf78a3e8b46dcaac95ac5d7ce6a"),
"20.9.0-linux_arm64": ("node-v20.9.0-linux-arm64.tar.xz", "node-v20.9.0-linux-arm64", "79c07c41c9f2410e35fd8dec61491ba63762e428bffa2ee0ff3aec1afe05d4b1"),
"20.9.0-linux_amd64": ("node-v20.9.0-linux-x64.tar.xz", "node-v20.9.0-linux-x64", "d11a5e06d6fda8d0cb1a759365d2b5e33c609f3c9f333fdc63e0522475dc0c89"),
"20.9.0-windows_amd64": ("node-v20.9.0-win-x64.zip", "node-v20.9.0-win-x64", "70d87dad2378c63216ff83d5a754c61d2886fc39d32ce0d2ea6de763a22d3780"),
"18.18.2-darwin_amd64": ("node-v18.18.2-darwin-x64.tar.gz", "node-v18.18.2-darwin-x64", "5bb8da908ed590e256a69bf2862238c8a67bc4600119f2f7721ca18a7c810c0f"),
"18.18.2-darwin_arm64": ("node-v18.18.2-darwin-arm64.tar.gz", "node-v18.18.2-darwin-arm64", "9f982cc91b28778dd8638e4f94563b0c2a1da7aba62beb72bd427721035ab553"),
"18.18.2-linux_arm64": ("node-v18.18.2-linux-arm64.tar.xz", "node-v18.18.2-linux-arm64", "8a5a03f6a742159c9aa0ae3a99b368cd938cf62f3a5522a2e5acbe6313710efe"),
"18.18.2-linux_amd64": ("node-v18.18.2-linux-x64.tar.xz", "node-v18.18.2-linux-x64", "f7cf590bc7153f3beaa9e1138d00e50d74df223f0bec61f63e7df65f7315b76a"),
"18.18.2-windows_amd64": ("node-v18.18.2-win-x64.zip", "node-v18.18.2-win-x64", "3bb0e51e579a41a22b3bf6cb2f3e79c03801aa17acbe0ca00fc555d1282e7acd"),
},
node_version = "20.9.0",
node_version = "18.18.2",
node_urls = [
"https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/dist/v{version}/{filename}",
],
Expand Down
3 changes: 1 addition & 2 deletions docs/user/plugins.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ Use it to create, edit and embed visualizations, and also to search inside an em

* https://github.com/sw-jung/kibana_markdown_doc_view[Markdown Doc View] (sw-jung) - A plugin for custom doc view using markdown+handlebars template.
* https://github.com/datasweet-fr/kibana-datasweet-formula[Datasweet Formula] (datasweet) - enables calculated metric on any standard Kibana visualization.
* https://github.com/pjhampton/kibana-prometheus-exporter[Prometheus Exporter] - exports the Kibana metrics in the prometheus format

NOTE: To add your plugin to this page, open a {kib-repo}tree/{branch}/docs/plugins/known-plugins.asciidoc[pull request].

Expand Down Expand Up @@ -183,4 +182,4 @@ you must specify the path to that configuration file each time you use the `bin/
0:: Success
64:: Unknown command or incorrect option parameter
74:: I/O error
70:: Other error
70:: Other error
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@
"url": "https://github.com/elastic/kibana.git"
},
"engines": {
"node": "20.9.0",
"node": "18.18.2",
"yarn": "^1.22.19"
},
"resolutions": {
"**/@hello-pangea/dnd": "16.2.0",
"**/@types/node": "20.9.0",
"**/@types/node": "18.18.5",
"**/@typescript-eslint/utils": "5.62.0",
"**/chokidar": "^3.5.3",
"**/globule/minimatch": "^3.1.2",
Expand Down Expand Up @@ -1379,7 +1379,7 @@
"@types/multistream": "^4.1.0",
"@types/mustache": "^0.8.31",
"@types/nock": "^10.0.3",
"@types/node": "20.9.0",
"@types/node": "18.18.5",
"@types/node-fetch": "2.6.4",
"@types/node-forge": "^1.3.1",
"@types/nodemailer": "^6.4.0",
Expand Down Expand Up @@ -1469,7 +1469,7 @@
"blob-polyfill": "^7.0.20220408",
"callsites": "^3.1.0",
"chance": "1.0.18",
"chromedriver": "^119.0.0",
"chromedriver": "^119.0.1",
"clean-webpack-plugin": "^3.0.0",
"cli-table3": "^0.6.1",
"copy-webpack-plugin": "^6.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Side Public License, v 1.
*/

import * as RxJS from 'rxjs';
import type { FullStoryApi } from './types';

export const fullStoryApiMock: jest.Mocked<FullStoryApi> = {
Expand All @@ -22,3 +23,10 @@ jest.doMock('./load_snippet', () => {
loadSnippet: () => fullStoryApiMock,
};
});

jest.doMock('rxjs', () => {
return {
...RxJS,
debounceTime: () => RxJS.identity,
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ describe('FullStoryShipper', () => {
);
});

afterEach(() => {
fullstoryShipper.shutdown();
});

describe('extendContext', () => {
describe('FS.identify', () => {
test('calls `identify` when the userId is provided', () => {
Expand Down Expand Up @@ -119,6 +123,21 @@ describe('FullStoryShipper', () => {
labels: { serverless_str: 'test' },
});
});

test('emits once only if nothing changes', () => {
const context = {
userId: 'test-user-id',
version: '1.2.3',
cloudId: 'test-es-org-id',
labels: { serverless: 'test' },
foo: 'bar',
};
fullstoryShipper.extendContext(context);
fullstoryShipper.extendContext(context);
expect(fullStoryApiMock.setVars).toHaveBeenCalledTimes(1);
fullstoryShipper.extendContext(context);
expect(fullStoryApiMock.setVars).toHaveBeenCalledTimes(1);
});
});
});

Expand Down
148 changes: 95 additions & 53 deletions packages/analytics/shippers/fullstory/src/fullstory_shipper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
Event,
IShipper,
} from '@kbn/analytics-client';
import { Subject, distinct, debounceTime, map, filter, Subscription } from 'rxjs';
import { get, has } from 'lodash';
import { set } from '@kbn/safer-lodash-set';
import type { FullStoryApi } from './types';
Expand Down Expand Up @@ -55,8 +56,18 @@ export interface FullStoryShipperConfig extends FullStorySnippetConfig {
* If this setting is provided, it'll only send the event types specified in this list.
*/
eventTypesAllowlist?: string[];
pageVarsDebounceTimeMs?: number;
}

interface FullStoryUserVars {
userId?: string;
isElasticCloudUser?: boolean;
cloudIsElasticStaffOwned?: boolean;
cloudTrialEndDate?: string;
}

type FullStoryPageContext = Pick<EventContext, typeof PAGE_VARS_KEYS[number]>;

/**
* FullStory shipper.
*/
Expand All @@ -67,6 +78,9 @@ export class FullStoryShipper implements IShipper {
private readonly fullStoryApi: FullStoryApi;
private lastUserId: string | undefined;
private readonly eventTypesAllowlist?: string[];
private readonly pageContext$ = new Subject<EventContext>();
private readonly userContext$ = new Subject<FullStoryUserVars>();
private readonly subscriptions = new Subscription();

/**
* Creates a new instance of the FullStoryShipper.
Expand All @@ -77,9 +91,54 @@ export class FullStoryShipper implements IShipper {
config: FullStoryShipperConfig,
private readonly initContext: AnalyticsClientInitContext
) {
const { eventTypesAllowlist, ...snippetConfig } = config;
const { eventTypesAllowlist, pageVarsDebounceTimeMs = 500, ...snippetConfig } = config;
this.fullStoryApi = loadSnippet(snippetConfig);
this.eventTypesAllowlist = eventTypesAllowlist;

this.subscriptions.add(
this.userContext$
.pipe(
distinct(({ userId, isElasticCloudUser, cloudIsElasticStaffOwned, cloudTrialEndDate }) =>
[userId, isElasticCloudUser, cloudIsElasticStaffOwned, cloudTrialEndDate].join('-')
)
)
.subscribe((userVars) => this.updateUserVars(userVars))
);

this.subscriptions.add(
this.pageContext$
.pipe(
map((newContext) => {
// 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
return PAGE_VARS_KEYS.reduce((acc, key) => {
if (has(newContext, key)) {
set(acc, key, get(newContext, key));
}
return acc;
}, {} as Partial<FullStoryPageContext> & Record<string, unknown>);
}),
filter((pageVars) => Object.keys(pageVars).length > 0),
// Wait for anything to actually change.
distinct((pageVars) => {
const sortedKeys = Object.keys(pageVars).sort();
return sortedKeys.map((key) => pageVars[key]).join('-');
}),
// We need some debounce time to ensure everything is updated before calling FS because some properties cannot be changed twice for the same URL.
debounceTime(pageVarsDebounceTimeMs)
)
.subscribe((pageVars) => {
this.initContext.logger.debug(
`Calling FS.setVars with context ${JSON.stringify(pageVars)}`
);
this.fullStoryApi.setVars('page', {
...formatPayload(pageVars),
...(pageVars.version ? getParsedVersion(pageVars.version) : {}),
});
})
);
}

/**
Expand All @@ -89,57 +148,11 @@ export class FullStoryShipper implements IShipper {
public extendContext(newContext: EventContext): void {
this.initContext.logger.debug(`Received context ${JSON.stringify(newContext)}`);

// FullStory requires different APIs for different type of contexts.
const {
userId,
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
...nonUserContext
} = newContext;

// Call it only when the userId changes
if (userId && userId !== this.lastUserId) {
this.initContext.logger.debug(`Calling FS.identify with userId ${userId}`);
// We need to call the API for every new userId (restarting the session).
this.fullStoryApi.identify(userId);
this.lastUserId = userId;
}

// User-level context
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<Pick<EventContext, typeof PAGE_VARS_KEYS[number]>> & Record<string, unknown>);

// FullStory requires different APIs for different type of contexts:
// User-level context.
this.userContext$.next(newContext);
// Event-level context. At the moment, only the scope `page` is supported by FullStory for webapps.
if (Object.keys(pageVars).length) {
this.initContext.logger.debug(`Calling FS.setVars with context ${JSON.stringify(pageVars)}`);
this.fullStoryApi.setVars('page', {
...formatPayload(pageVars),
...(pageVars.version ? getParsedVersion(pageVars.version) : {}),
});
}
this.pageContext$.next(newContext);
}

/**
Expand Down Expand Up @@ -184,9 +197,38 @@ export class FullStoryShipper implements IShipper {

/**
* Shuts down the shipper.
* It doesn't really do anything inside because this shipper doesn't hold any internal queues.
*/
public shutdown() {
// No need to do anything here for now.
this.subscriptions.unsubscribe();
}

private updateUserVars({
userId,
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
}: FullStoryUserVars) {
// Call it only when the userId changes
if (userId && userId !== this.lastUserId) {
this.initContext.logger.debug(`Calling FS.identify with userId ${userId}`);
// We need to call the API for every new userId (restarting the session).
this.fullStoryApi.identify(userId);
this.lastUserId = userId;
}

// User-level context
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));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ function buildRootCrumb({
i18n.translate('core.ui.primaryNav.cloud.projectLabel', {
defaultMessage: 'Project',
}),
// increase the max-width of the root breadcrumb to not truncate too soon
style: { maxWidth: '320px' },
popoverContent: (
<EuiContextMenuPanel
size="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down Expand Up @@ -176,6 +179,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down Expand Up @@ -232,6 +238,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,18 @@ export function Breadcrumbs({ breadcrumbs$ }: Props) {
};
});

return <EuiBreadcrumbs breadcrumbs={crumbs} max={10} data-test-subj="breadcrumbs" />;
return (
<EuiBreadcrumbs
breadcrumbs={crumbs}
data-test-subj="breadcrumbs"
// reduce number of visible breadcrumbs due to increased max-width of the root breadcrumbs
responsive={{
xs: 1,
s: 2,
m: 3,
l: 4,
xl: 7,
}}
/>
);
}
Loading

0 comments on commit 8931e00

Please sign in to comment.